Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion assets/scss/common/_custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,8 @@ $map-pulse-alpha: 0.18;
stroke: var(--bs-body-bg, #fff);
stroke-width: 3px;
paint-order: stroke;
// Purely a caption for the dot, which is already the hit target.
// The pointer goes to `.worldmap-hit-label`, the transparent copy of this name in
// the html layer above, which is what makes the name open the card.
pointer-events: none;
}

Expand Down Expand Up @@ -910,6 +911,49 @@ $map-pulse-offsets:
z-index: 4;
}

// The city's name as a second hover target for its card — see the template. The same
// text at the same size as `.worldmap-label`, painted transparent over it, so its box
// is the name's box. Everything is in map units turned into `cqw` (the layer is the
// query container and is the map's width, so one viewBox unit is 0.1cqw), and shrunk
// by `--mark-scale` exactly as the svg group is, so the two stay on top of each other
// at every width the names are drawn at.
//
// Anchored at the hit's centre, which is the dot's: `--label-dx` and `--label-dy` from
// the generated stylesheet are the svg label's own offset, and `dy` lands on its
// baseline. With `line-height: 1` the baseline is about 0.8em below the top of the
// line, so the box is lifted by that plus the padding — the padding is slack that
// makes a 12px name a little easier to land on than its glyphs alone.
.worldmap-hit-label {
display: none;
position: absolute;
left: calc(50% + var(--label-dx, 0) * 0.1cqw * var(--mark-scale, 1));
top: calc(50% + var(--label-dy, 0) * 0.1cqw * var(--mark-scale, 1));
padding: 0.2em;
font-size: calc(1.35cqw * var(--mark-scale, 1));
font-weight: 400;
line-height: 1;
white-space: nowrap;
color: transparent;
user-select: none;
transform: translate(-0.2em, -1em);
}

.worldmap-hit-label-end {
transform: translate(calc(-100% + 0.2em), -1em);
}

.worldmap-hit-label-middle {
transform: translate(-50%, -1em);
}

// Only where the svg draws the names — a target over a name that is not there would be
// a patch of empty map that opens a card.
@include media-breakpoint-up(xl) {
.worldmap-hit-label {
display: block;
}
}

// The ring is the focus indicator's job here too, but on its own it is a 22% wash
// that would not pass for one, so focus also gets an outline. On the card's side
// rather than the dot's, because the dot is 5px across at its smallest.
Expand Down
4 changes: 4 additions & 0 deletions hugo_stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@
"worldmap-country",
"worldmap-dot",
"worldmap-hit",
"worldmap-hit-label",
"worldmap-hit-label-end",
"worldmap-hit-label-middle",
"worldmap-hit-label-start",
"worldmap-hit-left",
"worldmap-hits",
"worldmap-key-title",
Expand Down
16 changes: 16 additions & 0 deletions layouts/_default/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,22 @@ <h1 class="home-title">{{ .Title }}</h1>
</p>
{{ end }}
</div>
{{/* A second way into the card: the city's name. The dots are a few
pixels across and hard to hit, while the name beside each one is
the thing a reader is actually looking at. This is the same text
as the svg label, set transparent at the same size and laid over
it (offsets from the generated stylesheet, anchor from the class),
so its box is the name's own box without anything measuring it.

Inside the hit rather than beside it, which is the whole trick:
hovering it is hovering `.worldmap-hit`, and a tap or click on it
focuses the hit, so the card opens through the same `:hover` and
`:focus-within` rules as the dot and no script is needed.
`aria-hidden` because the card head already names the place. */}}
{{ $short := .short -}}
{{ with .offset -}}
<span class="worldmap-hit-label worldmap-hit-label-{{ .anchor }}" aria-hidden="true">{{ $short }}</span>
{{- end }}
</div>
{{ end -}}
</div>
Expand Down
6 changes: 6 additions & 0 deletions layouts/partials/head/resource-hints.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
column of faces. */}}
{{ $room := cond (gt $pos.x (mul 0.5 $map.width)) (sub $left (div $size 2.0)) (sub (sub 100.0 $left) (div $size 2.0)) -}}
{{ $rules = $rules | append (printf ".worldmap-hit:nth-child(%d){left:%.3f%%;top:%.3f%%;width:calc(%.3f%% * var(--mark-scale, 1));--map-room:%.3f}" (add $i 1) $left $top $size $room) -}}
{{/* Where the city's name sits relative to its dot, in viewBox units — the same
hand-placed offset the svg label is drawn at, so the name's hover target in
`.worldmap-hit-label` lands on the name. */}}
{{ with $place.offset -}}
{{ $rules = $rules | append (printf ".worldmap-hit:nth-child(%d){--label-dx:%.1f;--label-dy:%.1f}" (add $i 1) (float .dx) (float .dy)) -}}
{{ end -}}
{{/* The point the svg's group for this mark is scaled about — its dot's centre, in
viewBox units. See `.worldmap-place` in the stylesheet; `nth-of-type` because the
groups are the only `<g>` in the svg, one per mark in this same order. */}}
Expand Down
Loading