Skip to content
Folio

Display

LinkArrow

The mark on a link that leaves the page.

Usage

TSX
import { LinkArrow } from '@misoto22/design'

Notes

The mark on a link that leaves the page — outbound, or on to a full index.

Call sites used to write a bare inside the link text, which inherited the link's own size (a 17px arrow beside a 17px word, competing with it) and was read aloud as "north east arrow" because nothing hid it.

inline-block is load-bearing twice over: it stops an underlined parent drawing its rule through the glyph, and it is what align is measured against. Sized in em, so it tracks whatever type it sits beside; coloured against paper, so a call site on a reversed plate passes its own colour.

Anatomy

LinkArrow anatomy
ElementDescription
Marker boxrequiredAn aria-hidden inline-block <span> carrying the 0.22em of lead-in, the 0.28em baseline lift and --ink-3-aa. inline-block is load-bearing twice over: it stops an underlined parent drawing its rule through the glyph, and it is what the alignment is measured against.
GlyphrequiredThe ↗ itself at 0.68em, so it tracks the type beside it instead of competing with it. Exported as EXTERNAL_LINK_ARROW, so a surface that is not React uses the same character.

Best practices

Do

  • Put it inside the <a>, as the last child. Outside it, it is an arrow pointing at a link the pointer misses by 0.22em.
  • Reach for EXTERNAL_LINK_ARROW when the surface is not React — a Markdown pipeline, an OG image, an email — so the mark stays one character rather than three near-identical arrows across a site.
  • Pass a colour through className on a reversed plate: it is set in --ink-3-aa, which is the AA floor against paper and close to invisible on ink.

Don’t

  • The arrow is not the announcement. It is aria-hidden, and target="_blank" is not announced either, so a link that opens a new tab has to say so in its own accessible name — otherwise this glyph is the only warning anyone gets, and only if they can see it.
  • Do not pin it to a px size. 0.68em is what makes one component right in body copy and in a heading; fixed at 11px it is correct in one of them and a speck in the other.
  • Do not put it on every row of an index. It marks a change of destination, so a list where every link leaves the site marks nothing at all and pays 0.22em a row for it.

Examples

default

The mark, inside the anchor and as its last child. Outside it, it is an arrow pointing at a link the pointer misses by 0.22em. The glyph is set in em so it tracks the type beside it rather than competing with it, and it is aria-hidden — nothing is announced by putting it here, so the link's own words still have to say where they go.

only where it leaves

Three links, one arrow. It marks a CHANGE of destination, so an index where every row carries one marks nothing at all and pays 0.22em a row for it. The outbound link says "opens in a new tab" in its own text, because neither the arrow nor target="_blank" is announced — without those words the glyph is the only warning anyone gets, and only if they can see it.

on a reversed plate

The one thing on this component meant to be overridden. It is set in --ink-3-aa, which is the AA floor against paper and close to invisible on ink, so a call site on a reversed plate passes its own colour through className. Everything else stays put: still the last child of the anchor, still 0.68em, still aria-hidden.

Re-exports

EXTERNAL_LINK_ARROW = '↗'

The glyph itself, exported so a non-React surface can use the same mark.

Accessibility

  • aria-hidden, so it is not read as “north east arrow” in the middle of a sentence.
  • Sized in em, so it tracks whatever type it sits beside instead of competing with it.