Skip to content

fix: make heading anchor links reachable on touch and visible on keyboard focus - closes #2709 - #2711

Open
tiagov8 wants to merge 1 commit into
mainfrom
fix/2709-heading-anchor-touch-and-focus
Open

fix: make heading anchor links reachable on touch and visible on keyboard focus - closes #2709#2711
tiagov8 wants to merge 1 commit into
mainfrom
fix/2709-heading-anchor-touch-and-focus

Conversation

@tiagov8

@tiagov8 tiagov8 commented Sep 9, 2026

Copy link
Copy Markdown
Member

cc @adamcogan @lukecookssw @kikibianc

Description

✏️
Fixes the heading anchor links (🔗 icon next to h2/h3/h4) on rule pages. Closes #2709.

The problem: the icon is hidden with opacity-0 and revealed with group-hover:opacity-100. Tailwind v4 gates hover variants behind @media (hover: hover), confirmed in the live production CSS:

@media (hover:hover){
  .group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}
}

So on touch devices the reveal can never fire — the anchor is permanently invisible while still reserving inline-block layout space, which wraps onto a second line and produces an unexplained blank line under headings. Separately, there was no focus-visible state, so keyboard focus landed on a fully transparent link (WCAG 2.4.7 failure).

The fix — one line, two variants added on top of the existing hover reveal:

  • pointer-coarse:opacity-100 — permanently visible where touch is the primary input.
  • focus-visible:opacity-100 — visible on keyboard focus.

Desktop behaviour is unchanged: headings stay clean and hover-reveal the icon. group relative is deliberately retained on the heading, since group-hover is still in use.

This is the hybrid option from the issue, chosen over "always visible" to avoid a persistent link icon next to every heading on every rule page.

Verification

Compiled the exact class list with Tailwind CLI v4.2.4 (the version pinned in package.json) to confirm the utilities generate correctly and in a safe cascade order:

.opacity-0 { … }                                           /* line 175 */
.group-hover\:opacity-100 { @media (hover: hover) { … } }   /* line 187 */
.focus-visible\:opacity-100 { &:focus-visible { … } }       /* line 194 */
.pointer-coarse\:opacity-100 { @media (pointer: coarse) { … } } /* line 199 */

All three reveal variants are emitted after the opacity-0 base, so with equal specificity each correctly overrides it. They also cannot conflict with one another, since all three set opacity-100.

Known trade-off

On hover-capable desktop devices the invisible icon still reserves layout space, so a heading landing exactly on the wrap boundary can still produce a phantom line there. That is the accepted cost of keeping desktop headings clean — the problem is resolved where it actually bites, on touch. The alternative (always visible) is documented in #2709 if we'd rather eliminate it everywhere.

Note

Supersedes #2710, which implemented the "always visible" option before the direction changed. That PR also stripped group relative from the heading, which would have broken the desktop reveal.

Screenshot (optional)

✏️
Not included — the change is a visibility state that needs a real touch device or keyboard focus to demonstrate. Worth a quick check on the deploy preview: open a rule page on a phone and confirm the 🔗 icon is visible next to headings, then tab through on desktop and confirm it appears on focus.

🤖 Generated with Claude Code

…oard focus - closes #2709

Heading anchor icons were hidden with opacity-0 and revealed only via
group-hover. Tailwind v4 gates hover variants behind @media (hover: hover),
so the reveal could never fire on touch devices - the icon was permanently
invisible while still reserving inline-block layout space, producing an
unexplained extra line under headings.

Adds two variants on top of the existing hover reveal:
- pointer-coarse:opacity-100 - always visible where touch is the primary
  input, so mobile users can reach the anchor at all.
- focus-visible:opacity-100 - visible on keyboard focus, fixing a WCAG
  2.4.7 failure where focus landed on a fully transparent link.

Desktop behaviour is unchanged: headings stay clean and hover-reveal the
icon. The group and relative classes are deliberately retained, since
group-hover is still in use.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug - Heading anchor links are unreachable on mobile and reserve invisible layout space

1 participant