<link-surface> github npm jayfreestone.com ↗

Link Surface: an accessible, framework-agnostic block link for cards & more.

link-surface progressively expands a real anchor’s plain-click target across otherwise inert content. This lets whole cards become clickable areas, while allowing for other links and interactive elements to remain unaffected.

Basic usage

Mark one real fallback anchor as the primary link. Interactive elements are left alone automatically. Optionally use data-link-surface-ignore to explicitly exclude content and everything inside it.

HTML link-surface API
<link-surface>
  <h2>
    <a data-primary-link href="/articles/card-design-woes">
      Cards
    </a>
  </h2>

  <p>Ten common pitfalls to avoid when designing cards.</p>

  <button type="button">Save — does not open the article</button>

  <p data-link-surface-ignore>
    This text is explicitly excluded from the link target.
  </p>
</link-surface>

Examples

A plain click anywhere on inert card content is proxied to the headline anchor (watch the log at the bottom of the page). Secondary links, buttons, and marked widgets keep their own behavior. Selecting text and releasing never navigates.

Card design woes

Ten common pitfalls to avoid when designing card components, and why wrapping everything in one big anchor is the worst of them.

Select me

Try selecting this sentence and letting go. A surface never hijacks a text selection or a modified click.

The escape hatch

No selector can detect every interactive custom element, so this tag rail is marked data-link-surface-ignore. Clicks on it don't activate the link.

exampletagsstillclickable

No primary link here

This surface has no a[data-primary-link], so it never becomes ready: it fails the :has(a[data-primary-link][href]) style rule, so no accent, no pointer cursor, no proxying. The element degrades to plain markup.

An intentionally inert card

Demo links point at fragment URLs and are intercepted here purely so the page doesn’t jump.

Event log Ready: click anywhere on a linked card.