Skip to content

Commit

Permalink
Revamp header layout (#205)
Browse files Browse the repository at this point in the history
This improves the header:

* Makes all touch targets at least 44px, the accessibility minimum
* Moves copy link icon to the header
* Removes the "Parking Lot Map" text
* adds a teal border underneath

It also adds more explanatory text to the header in the scorecard, now
saying "Parking lots in City, ST" to better explain what people are
seeing.

<details><summary>before: mobile</summary>

<img width="377" alt="Screenshot 2024-07-07 at 4 27 36 PM"
src="https://github.com/ParkingReformNetwork/parking-lot-map/assets/14852634/8f94c488-40c1-4085-9c66-94adc49ebf4a">
</details>

<details><summary>before: desktop</summary>

<img width="1108" alt="Screenshot 2024-07-07 at 4 26 40 PM"
src="https://github.com/ParkingReformNetwork/parking-lot-map/assets/14852634/610c9d85-4fe2-4e12-bf16-0b9a11f81e10">
</details>

<details><summary>after: mobile</summary>

<img width="374" alt="Screenshot 2024-07-07 at 4 27 00 PM"
src="https://github.com/ParkingReformNetwork/parking-lot-map/assets/14852634/3254f3b5-77f9-4512-9e79-cea065ac7c42">
</details>

<details><summary>after: desktop</summary>

<img width="1114" alt="Screenshot 2024-07-07 at 4 25 55 PM"
src="https://github.com/ParkingReformNetwork/parking-lot-map/assets/14852634/3a0cdcee-4f7d-4d94-81ea-837aaa75b5a7">
</details>

--

Removing the "Parking Lot Map" text achieves two things:

* Allows us to fit the header on a single line, even on mobile. This
allows more screen real estate for the map itself and scorecard
* Improves information hierarchy. The name of the map is not as
important as the map itself and explaining what you're seeing on the map
(i.e. the unexpanded accordion)

People will still see the name of the map because it's often accessed
from the resources folder with all the additional context.

--

Finally, this improves the size and positioning of the donate button.
  • Loading branch information
Eric-Arellano authored Jul 7, 2024
1 parent a2b3a6d commit 147db96
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 126 deletions.
28 changes: 18 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,28 @@

<body>
<header>
<div class="navigation">
<span class="site-title">Parking Lot Map</span>
<select
single
name="city-dropdown"
class="city-dropdown"
id="city-dropdown"
aria-label="select the city"
></select>
</div>
<select
single
name="city-dropdown"
class="header-dropdown"
id="city-dropdown"
aria-label="select the city"
></select>
<div class="header-icons">
<div class="header-about-icon-container">
<i class="fa-solid fa-circle-info" title="About"></i>
</div>
<a href="#" class="header-share-icon-container"
><i
class="share-link-icon fa-solid fa-link fa-lg"
title="copy link"
></i
><i
class="share-check-icon fa-solid fa-check fa-lg"
title="link successfully copied"
style="display: none"
></i>
</a>
<a
class="header-link-icon-container"
href="https://parkingreform.org/parking-lot-map/"
Expand Down
3 changes: 2 additions & 1 deletion src/css/_controls.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
@use "theme/colors";
@use "theme/touchable-icons";
@use "theme/typography";
@use "header";

$label-font-size: typography.$font-size-md;
$zoom-controls-top-offset: 10px;
$zoom-controls-top-offset: calc(70px - header.$header-height);
$outer-border-thickness: 2px;
$option-divider: 1px solid colors.$gray-light-translucent;

Expand Down
31 changes: 15 additions & 16 deletions src/css/_donate.scss
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
@use "theme/breakpoints";

div.donate-button {
position: absolute;
border-radius: 5px;
left: 9px;
bottom: 19px;
left: 10px;
z-index: 2001;
width: 100px;
}

div.donate-button a img {
width: 100%;
border-radius: 4px;
}
// `bottom` is set so high to avoid covering the attribution
// on small screens, since it wraps to two lines.
bottom: 35px;
@include breakpoints.gt-xs {
bottom: 10px;
}

@media only screen and (max-width: 830px) {
div.donate-button {
bottom: 43px;
width: 90px;
@include breakpoints.gt-sm {
width: 105px;
}
}

@media only screen and (max-width: 480px) {
div.donate-button a img {
width: 70%;
a img {
width: 100%;
border-radius: 4px;
}
}
103 changes: 53 additions & 50 deletions src/css/_header.scss
Original file line number Diff line number Diff line change
@@ -1,80 +1,83 @@
@use "theme/breakpoints";
@use "theme/colors";
@use "theme/touchable-icons";
@use "theme/typography";

$header-y-padding: 10px;
$header-border-bottom-size: 4px;
$header-height: calc(
touchable-icons.$min-touch-target + ($header-y-padding * 2) +
$header-border-bottom-size
);

header {
width: 100%;
padding: 0.4em 1em;
display: flex;
align-items: center;

background-color: colors.$gray-light;
color: colors.$white;
font-size: 1.3em;
padding: $header-y-padding 10px;

display: flex;
background-color: colors.$gray-light;
border-bottom: $header-border-bottom-size solid colors.$teal;
}

.header-icons {
display: flex;

margin-left: auto;
cursor: pointer;

svg {
color: colors.$white;
}
.header-about-icon-container,
.header-share-icon-container,
.header-link-icon-container {
height: touchable-icons.$min-touch-target;
width: touchable-icons.$min-touch-target;

.header-about-icon-container {
margin-right: 0.75em;
display: inline-flex;
align-items: center;
justify-content: center;
}

margin-left: auto;
svg {
color: colors.$white;
height: touchable-icons.$icon-size-md;
width: touchable-icons.$icon-size-md;
}
}

@media only screen and (min-width: 48em) {
header {
align-items: center;
font-size: 1.75em;
}
.choices {
margin-bottom: 0;
}

.navigation {
flex: 1;
display: flex;
align-items: center;
margin-right: 1em;
}
.choices[data-type*="select-one"] {
.choices__inner {
border-radius: 10px;
color: colors.$black;
font-size: typography.$font-size-base;
line-height: 1.2; // To vertically center the text.

.site-title {
flex: 1;
}
height: touchable-icons.$min-touch-target;

#city-dropdown {
display: flex;
align-items: center;
gap: 0.7em;
height: 40px;
min-width: 220px;
@include breakpoints.gt-xs {
min-width: 300px;
}
}
}

.choices__inner {
border: 2px solid colors.$black-translucent;
border-radius: 10px;
color: colors.$black;
height: 40px;

@media only screen and (min-width: 20em) {
min-width: 20em;
.choices__input {
// Cannot be less than 16px due to iOS autozoom:
// https://weblog.west-wind.com/posts/2023/Apr/17/Preventing-iOS-Safari-Textbox-Zooming
font-size: typography.$font-size-base;
}
}

.choices__item--selectable {
font-size: 14px;
height: 40px;
.choices__heading {
font-size: typography.$font-size-sm;
cursor: default;
}

.choices__input {
/*
* This is necessary to prevent autozoom on iOS
* for accessibility reasons. See:
* https://weblog.west-wind.com/posts/2023/Apr/17/Preventing-iOS-Safari-Textbox-Zooming
*/
font-size: 16px;
div.choices__item.choices__item--choice.choices__item--selectable {
font-size: typography.$font-size-base;
height: touchable-icons.$min-touch-target;
}

.choices__list--dropdown,
Expand Down
34 changes: 11 additions & 23 deletions src/css/_scorecard.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
@use "theme/breakpoints";
@use "theme/colors";
@use "theme/touchable-icons";
@use "theme/typography";
@use "header";

$outer-padding: 15px;
$padding-between-elements: 10px;
Expand All @@ -27,30 +29,26 @@ $border-radius: 10px;

float: right;
position: fixed;
right: 11px;
top: 100px;
right: 10px;
top: calc(header.$header-height + 12px);

border-radius: $border-radius;
}

.scorecard-header {
.scorecard-title {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: $outer-padding;
padding-bottom: $padding-between-elements;
padding-left: $outer-padding;
padding-right: $outer-padding;
}

.scorecard-title {
flex: 1;
margin-top: $outer-padding;
margin-bottom: $padding-between-elements;
margin-left: $outer-padding;
margin-right: $outer-padding;
line-height: 1.1;

color: colors.$teal;
font-weight: bold;
font-size: typography.$font-size-xl;
line-height: 1.1;
margin-top: 0;
margin-bottom: 0;
}

.scorecard-accordion-toggle {
Expand Down Expand Up @@ -107,16 +105,6 @@ $border-radius: 10px;
padding-right: $outer-padding;
}

.share-icon-container {
margin-left: 10px;

svg {
color: colors.$teal !important;
font-size: typography.$font-size-lg;
padding-bottom: 2px;
}
}

.popup-button a {
display: inline-block;
padding: 10px;
Expand Down
8 changes: 1 addition & 7 deletions src/js/scorecard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ import setUpShareUrlClickListener from "./share";

const generateScorecard = (entry: ScoreCardDetails): string => {
const header = `
<div class="scorecard-header">
<h1 class="scorecard-title">${entry.name}</h1>
<a href="#" class="share-icon-container">
<i class="share-link-icon fa-solid fa-link fa-xl" title="Copy link"></i>
<i class="share-check-icon fa-solid fa-check fa-xl" title="Link Copied!" style="display: none"></i>
</a>
</div>
<h1 class="scorecard-title">Parking lots in ${entry.name}</h1>
<p>${entry.percentage} of the central city is off-street parking</p>
`;

Expand Down
12 changes: 3 additions & 9 deletions src/js/share.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,9 @@ const switchIcons = (shareIcon: HTMLAnchorElement): void => {
};

const setUpShareUrlClickListener = (cityId: CityId): void => {
// The event listener is on `map` because it is never erased, unlike the copy button
// being recreated every time the map moves. This is called "event delegation".
const map = document.querySelector("#map");
if (!(map instanceof Element)) return;
map.addEventListener("click", async (event) => {
const clicked = event.target;
if (!(clicked instanceof Element)) return;
const iconContainer = clicked.closest(".share-icon-container");
if (!(iconContainer instanceof HTMLAnchorElement)) return;
const iconContainer = document.querySelector(".header-share-icon-container");
if (!(iconContainer instanceof HTMLAnchorElement)) return;
iconContainer.addEventListener("click", async () => {
const shareUrl = determineShareUrl(window.location.href, cityId);
await copyToClipboard(shareUrl);
switchIcons(iconContainer);
Expand Down
Loading

0 comments on commit 147db96

Please sign in to comment.