Links
A destination is a link and an action is a button. Every link here is a real <a href>: the browser navigates, so middle-click, ⌘- or Ctrl-click, a new tab, Copy link and Enter all work. Nothing navigates from a click handler.
Design examples
Section titled “Design examples”Underlined text links and whole-row links keep their native navigation semantics.
<section class="specimen">
<ds-row class="line" ><a class="ds-link" href="#essay">Read the essay</a></ds-row><ds-row class="line" ><a class="ds-link" href="#sources">View the sources</a></ds-row><ds-gap></ds-gap><ds-row class="line" href="#notes"><span class="mark"><ds-icon type="page" size="large" aria-hidden="true"></ds-icon></span><ds-text literal >Notes on daylight</ds-text></ds-row>
</section>
<style>
.specimen { width: 100%; min-width: 0; --cell: calc(20px * var(--sf, 1)); }
.specimen .line { width: 100%; }
.specimen .grow { flex: 1; min-width: 0; }
.specimen .muted { color: var(--ds-text-color-muted); }
.specimen .mono { --ds-typeface-regular: var(--ds-typeface-mono); font-variant-numeric: tabular-nums; }
.specimen .value { width: calc(4 * var(--cell)); text-align: right; }
.specimen .mark { display: inline-flex; align-items: flex-end; width: var(--cell); height: var(--ds-control-height); flex: 0 0 var(--cell); }
.specimen .columns { display: flex; flex-wrap: wrap; gap: var(--cell); }
.specimen .columns > * { min-width: 0; }
.specimen fieldset { border: 0; padding: 0; margin: 0; }
.specimen legend { padding: 0; }
.specimen label { display: flex; align-items: flex-end; gap: calc(var(--cell) / 2); min-height: var(--cell); }
.specimen ds-panel { height: calc(10 * var(--cell)); }
</style> A quiet text link beside a stronger link button.
<section class="specimen">
<ds-row class="line" ><a class="ds-link" href="#programme">Programme</a><ds-button primary href="#reservation">Reserve a seat</ds-button></ds-row>
</section>
<style>
.specimen { width: 100%; min-width: 0; --cell: calc(20px * var(--sf, 1)); }
.specimen .line { width: 100%; }
.specimen .grow { flex: 1; min-width: 0; }
.specimen .muted { color: var(--ds-text-color-muted); }
.specimen .mono { --ds-typeface-regular: var(--ds-typeface-mono); font-variant-numeric: tabular-nums; }
.specimen .value { width: calc(4 * var(--cell)); text-align: right; }
.specimen .mark { display: inline-flex; align-items: flex-end; width: var(--cell); height: var(--ds-control-height); flex: 0 0 var(--cell); }
.specimen .columns { display: flex; flex-wrap: wrap; gap: var(--cell); }
.specimen .columns > * { min-width: 0; }
.specimen fieldset { border: 0; padding: 0; margin: 0; }
.specimen legend { padding: 0; }
.specimen label { display: flex; align-items: flex-end; gap: calc(var(--cell) / 2); min-height: var(--cell); }
.specimen ds-panel { height: calc(10 * var(--cell)); }
</style> A text link
Section titled “A text link”.ds-link (from controls.css) is a link in running text: the text’s own ink, underlined by a hairline 2px below the letters. The line turns to the full ink under the pointer, a visited link is drawn in the muted ink, and keyboard focus shows the shared focus ring. Its words keep their sentence case.
<a class="ds-link" href="/icons/">Browse the icons</a>| Token | Default | What it sets |
|---|---|---|
--ds-link-color | The text’s colour | The link’s ink. |
--ds-link-visited-color | --ds-text-color-muted | The ink of a visited link. |
--ds-link-line-color | The ink at 40% | The underline at rest. |
--ds-link-hover-line-color | The ink | The underline under the pointer. |
A plain text link
Section titled “A plain text link”Add ds-link--plain for a text link without an underline, including on hover. Use it in clearly labelled navigation or related-component lists. It keeps the normal link behaviour, visited colour and visible keyboard focus.
Example uses Footer · Prose · Table
<a class="ds-link ds-link--plain" href="/4-page/footer/">Footer</a>A link that looks like a button
Section titled “A link that looks like a button”Give ds-button an href and its face becomes a link (<a part="control">) drawn exactly as the button, in every variant and state:
<ds-button secondary href="/icons/">Icons</ds-button><ds-button href="https://example.com/" blank>Example</ds-button>React products use ButtonLink from the button adapter; the anchor is the light-DOM control, and refs and handlers reach it:
import { ButtonLink } from './design/react/button';<ButtonLink secondary href="/icons/">Icons</ButtonLink>New tabs
Section titled “New tabs”blank on ds-button is target="_blank". A new tab gets rel="noopener noreferrer" unless rel says otherwise, on the element and in ButtonLink alike. target and rel are passed to the link as written.
Disabled links
Section titled “Disabled links”A disabled link has no href (and no target), so it cannot navigate, and it is left out of the tab order. It stays a link to assistive technology with role="link" and aria-disabled="true", dimmed like a disabled button. For a.ds-button and .ds-link, remove the href yourself and set aria-disabled="true".