Skip to content

COMPONENT

Link

Two marks a link can wear. One reads as the text around it until you touch it; the other says the destination is somewhere else.

Inside a spec row

The values keep the row's type and ink. Hover one, then tab to it.

ROLE Sole engineer
STACK Go, OpenGL
SHIPPED 2026
HTML
<div class="rule-stack" style="width:100%">
  <div class="rule-row rule-row-spec">
    <span class="rule-row-key">ROLE</span>
    <span class="rule-row-value">Sole engineer</span>
  </div>
  <div class="rule-row rule-row-spec">
    <span class="rule-row-key">STACK</span>
    <span class="rule-row-value">
      <a class="link-quiet" href="#go">Go</a>, <a class="link-quiet" href="#opengl">OpenGL</a>
    </span>
  </div>
  <div class="rule-row rule-row-spec">
    <span class="rule-row-key">SHIPPED</span>
    <span class="rule-row-value">2026</span>
  </div>
</div>

In a footer line

Two quiet links beside a loud one. The contrast is the point of both.

HTML
<div class="article-foot" style="width:100%">
  <span class="article-foot-filed">
    FILED UNDER β€” <a class="link-quiet" href="#editors">EDITORS</a>, <a class="link-quiet" href="#tooling">TOOLING</a>
  </span>
  <a class="article-foot-next" href="#next">Next: selection models β†—</a>
</div>

One of them leaves the site

`link-out` adds the arrow and nothing else, so it composes with the quiet link or rides on a plain one. Compare the two in the sentence: same ink, same weight, and only one of them tells you where you are about to end up.

On Mondays and Thursdays at 7:30 pm you can find me at a studio across town, and the rest of the week at my desk.

HTML
<p class="measure">
  On Mondays and Thursdays at 7:30 pm you can find me at
  <a class="link-quiet link-out" href="https://example.com" target="_blank" rel="noopener">a studio across town</a>,
  and the rest of the week at
  <a class="link-quiet" href="#desk">my desk</a>.
</p>

Reference

Read from components/link.css when this page was built, so it cannot fall behind the stylesheet.

CLASSES.link-quiet.link-out
READS--ds-accent--ds-focus-ring--ds-focus-width--ds-gap-tight--ds-hairline

Notes

INHERITING THE COLOUR IS THE WHOLE COMPONENT

Every bare a is painted with the accent by the base layer. Drop one into a spec row without this class and that single value turns blue while its neighbours stay ink β€” which reads as a rendering fault rather than as a link. That shipped once, on a linked heading, and no check found it; someone looked at the page.

THE ARROW IS SILENT, AND THAT IS THE HARD PART

Several screen readers announce generated content, so a bare content: 'β†—' reads the glyph out at the end of every external link. The content shorthand takes alternative text after a slash β€” 'β†—' / '' β€” which sets it to nothing. A browser too old for that syntax drops the whole declaration and simply draws no arrow, which is the right way round to fail: a missing mark, never a spoken one.

It marks the link and sets neither target nor rel, because CSS cannot. Those are the caller's β€” and prefer rel="noopener" alone over noreferrer when the destination is somebody you want to send traffic to, since noreferrer also strips the referrer that tells them you did.

THE UNDERLINE IS RESERVED, NOT ADDED

A transparent bottom border sits there at rest and gains a colour on hover, so the baseline never moves. Adding the border only on hover reflows every line of a wrapped list as the cursor crosses it β€” most visibly on the comma-separated runs this component exists for.

WHEN NOT TO USE IT

When the target is a control rather than a word in a sentence, reach for .btn-quiet instead: that one is a box with its own padding and its own hit area. This one is deliberately inline, and it relies on the WCAG 2.5.8 exception for a target inside a sentence β€” enlarging it would break the line it belongs to. A quiet link that is not in a text run is not covered by that exception and needs its own block size.