DEV Community

FrozonFreak
FrozonFreak

Posted on Originally published at thewebhig.hashnode.dev

Links navigate, buttons act — Web HIG tip #3

Most "this button doesn't work" bugs are really a link pretending to be a button, or a button pretending to be a link.

Web HIG tip #3 (Quick #14, #16, #67, #68): Links navigate. Buttons act. Never make navigation behave like an action, and never build controls out of <div onClick>.

Why it matters

Users, browsers, and assistive tech all treat links and buttons differently:

  • A link goes somewhere. It can be opened in a new tab, copied, bookmarked, and middle-clicked. Screen readers announce it as "link". Enter activates it.
  • A button does something on this page: submit, save, open a dialog, toggle a panel. Screen readers announce it as "button". Enter and Space activate it.

When you mix them up, something quietly breaks:

  • A <button> that calls router.push() can't be opened in a new tab or copied
  • An <a href="#"> that deletes a row adds a junk history entry, and Space scrolls the page instead of firing
  • A <div onClick> gets no focus, no keyboard support, and no role, so keyboard and screen-reader users can't use it at all

The rule of thumb

Ask: does this change the URL?

  • Yes → use <a href="...">
  • No, it changes something here → use <button type="button"> (or type="submit" inside a form)
<!-- Navigation: it's a link, even if it looks like a button -->
<a class="btn btn-primary" href="/projects/new">New project</a>

<!-- Action: it's a button, even if it looks like a link -->
<button type="button" class="link-style" onclick="openFilters()">Filters</button>
Enter fullscreen mode Exit fullscreen mode

Styling is separate from semantics. A link can look like a button and a button can look like a link. Pick the element for behavior, then style it.

Do this instead

  • Use native <a> and <button> before reaching for ARIA roles
  • Never put click handlers on <div> or <span> for interactive controls
  • If something navigates, give it a real href so new tab, copy link, and Back all work
  • Keep the platform conventions people expect: links look like links, buttons look like buttons

Quick check for your app

Tab through one screen with the keyboard only. Every control should take focus, show a visible focus ring, and work with Enter (and Space for buttons). Then right-click each "link" and try "Open in new tab". Anything that fails one of those is the wrong element.


The Web HIG is a behavioral contract for how the web should behave, not a component library. Design systems define look. The Web HIG defines behave.

Top comments (0)