Designer view

Link

An interactive element that navigates the user to another resource — another page, an anchor within the current page, an external URL, a downloadable file, or a `mailto:` / `tel:` target. Distinct from Button (which performs an action without navigation). Renders as `<a href>` in HTML and inherits the entire native anchor contract: middle-click opens in a new tab, right-click exposes the URL, copy- as-link works, the URL is visible in the status bar.

When to use

Use

When the user needs to navigate to another resource — another page, an anchor on the current page, an external URL, a downloadable file, or a `mailto:` / `tel:` target. Default activator for navigation.

Avoid

For in-page actions that do not navigate (form submit, modal open, panel toggle) — that is `Button`. For the disclosure affordance of a menu — that is `MenuButton`. For decorative in-prose markers that should not be interactive — that is plain text (or a `<dfn>` / `<abbr>` element).

Versus related

  • button

    `Link` navigates; `Button` performs an action without navigation. Visual styling may converge (button-styled link, link-styled button), but the semantic choice never does — middle-click, copy-link, status-bar URL preview, and keyboard activation (Enter-only vs Enter+Space) all depend on the underlying element.

  • icon-button

    `IconButton` is a button rendered as an icon plus `aria-label`. A link rendered as an icon (`<a>` wrapping an icon with `aria-label`) is still a Link if it navigates; IconButton only when it triggers an action.

  • menu-button

    `MenuButton` opens a menu of options and exposes `aria-haspopup="menu"`. `Link` navigates immediately on activation. A "links-list rendered as a menu" pattern is either a real menu (MenuButton + menu items) or a navigation list with `<a>` items — never both.

Highlight
Fig 1.1 · Link · Designer view
Designer

Figma anatomy

Slot Figma type Hint
root text Inline text or auto-layout horizontal frame; bound to "destination" property documented separately
label text Inline text style; underline applied by variant treatment
icon-trailing instance Icon component instance; visibility bound to the relevant property
visited-marker rectangle 6×6 dot or label-color-shift; visibility bound to "visited" state
Designer

Token usage per slot

root
color
  • foregroundcolor.text.accent
  • ringcolor.border.focus
typography
  • sizetext.md
  • weightweight.medium
label
color
  • foregroundcolor.text.accent
typography
  • sizetext.md
  • weightweight.medium
  • trackingtracking.normal
icon-trailing
color
  • foregroundcolor.text.accent
visited-marker
color
  • backgroundcolor.text.muted
Both

Figma ↔ Code property map

FigmaTypeCodeNotes
VariantVariantvariantMaps inline / standalone / button-styled.
SizeVariantsizesm / md / lg. Mostly relevant for standalone variant; inline links inherit surrounding text size.
EmphasisVariantemphasissubtle / default / strong. Drives colour intensity and underline thickness.
ExternalBooleanexternalToggles trailing-icon visibility and adds `target="_blank" rel="noopener noreferrer"` plus a "(opens in new tab)" SR announcement.
DownloadBooleandownloadToggles trailing-icon visibility and sets the `download` attribute. Cross-origin caveat documented in mistakes.
Has Trailing IconBooleaniconTrailingSlot-visibility toggle; auto-true when external or download is true.
Trailing IconInstance SwapiconTrailingSwap the trailing-icon component (chevron, arrow, download-arrow, external-square).
LabelTextchildrenDefault slot — the link text.
VisitedBooleandata-visitedFigma-only state for design preview; in production the `:visited` pseudo-class drives the visual without a code prop.
Both

Internationalisation

RTL · mirroring

Underline and text alignment follow the document direction (LTR underline below the baseline; RTL same — underlines are direction-neutral). Trailing icons (external arrow, download arrow) move from inline-end to inline-start visually but remain semantically "trailing"; their glyphs do *not* mirror (a download arrow points down in both directions; an external-square glyph is direction-neutral). Numerals in link text follow the locale's preferred numeral system. Chevrons indicating jump direction (anchor-down, see-also-right) flip horizontally to preserve semantic direction.

Text expansion

Link labels can grow significantly. Inline links inside prose inherit line-wrap; standalone links may need a larger inline-size budget. Avoid hard-coding link min-width; use the label's natural width plus padding (button-styled variant only). Generic phrases like "Read more" / "Learn more" expand differently in DE / RU / FI — DE "Mehr erfahren" is shorter than "Read more"; RU "Подробнее" is longer; the canonical surface is sized for the longest expected expansion.

Both

Variants, properties, states

Variants

Structurally different versions of the component.

inlinestandalonebutton-styled

Properties

The same component, parameterised.

PropertyType
externalboolean
downloadboolean
sizesm | md | lg
emphasissubtle | default | strong

States

Browser/user-driven (interactive) vs. app-driven (data).

KindStates
interactive
hoverfocus-visibleactivevisited
data
disabledloading
Both

Figma↔Code mismatches

  1. 01
    Figma

    An underlined text style drawn for inline links in body prose

    Code

    A `<a>` element with `text-decoration: underline` plus `:hover` reinforcement and `:focus-visible` ring

    Consequence

    Designers may rely on Figma's underline rendering and forget that `text-decoration` interacts with line-height and descender clearance differently per browser. Removing the underline entirely (relying on color alone) violates WCAG 1.4.1 (Use of Color); Figma can show a styled link without an underline and pass a visual review the rendered version would fail.

    Correct

    Document underline as the canonical default for inline links; colour-only differentiation is the documented WCAG failure case to avoid. Standalone and button-styled variants may opt out of underline only when they carry sufficient non-color affordances (button-styled buttons, distinct background).

  2. 02
    Figma

    A "link styled as button" variant drawn alongside actual buttons

    Code

    A `<a class="button">` with button visual treatment but anchor semantics

    Consequence

    Designers and developers diverge on whether the element is a Link or a Button — they look identical visually but their keyboard contracts differ (Enter only on `<a>`, Enter + Space on `<button>`), middle-click behavior differs, and form participation differs. The Figma file does not encode the semantic choice.

    Correct

    Treat the semantic question (does this navigate, or does it perform an in-page action?) as the canonical distinguisher. A "link styled as a button" remains a Link with anchor semantics; a button-styled `<a>` does not get Spacebar activation. Document the variant explicitly as `variant: button-styled` so the visual treatment is named and the semantic choice stays clear.

  3. 03
    Figma

    External link icon drawn as a separate static glyph next to the label

    Code

    A `::after` pseudo-element on `[target="_blank"]` or a slot-based icon driven by the `external` property

    Consequence

    Designers may forget the "external" indicator on individual links and developers may forget to set `rel="noopener noreferrer"`. The two artefacts disagree about which links go external; users cannot predict before clicking which links will open a new tab.

    Correct

    Model `external` as a boolean property. The Figma component exposes it as a Boolean; the code wires it to both the visual icon and the `target="_blank" rel="noopener noreferrer"` attributes plus an `aria-label` suffix or hidden text announcing "(opens in new tab)".

  4. 04
    Figma

    Disabled link drawn as greyed-out text with no underline

    Code

    There is no `disabled` attribute on `<a>` — `aria-disabled="true"` plus `tabindex="-1"` plus removed `href` is the closest equivalent

    Consequence

    Designers may treat "disabled link" as a real state; developers shipping it implement disabled inconsistently — sometimes the `<a>` is still keyboard-reachable but a no-op (confusing), sometimes it's removed from focus order entirely (announced as nothing).

    Correct

    Document that "disabled link" is not a native concept. Either replace the `<a>` with a span (no semantic), or use `aria-disabled="true"` plus an `onClick` guard plus removal of `href` (announces as a non-focusable disabled link in some SR). Prefer not rendering the link at all when the destination is genuinely unavailable.

Designer

Common mistakes

Accessibility hints
Slot Accessibility hint
root Always render as `<a href="...">`. A link without `href` has no role, is not focusable, and is not announced as a link by SR. Avoid `<div>` or `<span>` with click handlers and `role="link"` — the native element is always preferable. Visited state must be perceivable (CSS `:visited` styled beyond the page baseline) for content where revisit recall matters.
label Plain text node. Avoid generic phrases ("read more", "click here") — they are uninformative when SR users navigate by link list. Distinguish links to the same destination from links to different destinations through the link text alone, not just through surrounding context.
icon-trailing Decorative when its meaning is also conveyed in the label text or the link's accessible name (e.g. "Download report, opens PDF" with a download icon). When the icon carries meaning the label omits, surface the meaning in `aria-label` on the link, not on the icon. Per WCAG, "opens in new tab" / "external link" must be announced for SR users.
visited-marker Visited state is rendered visually only. SR does not announce "visited" by default. For lists where revisit recall matters (search results, archives), pair the visual marker with an `aria-describedby` reference to a visually-hidden "visited" text — but only on links the user is meant to revisit-aware.