216digital.
Web Accessibility

ADA Risk Mitigation
Prevent and Respond to ADA Lawsuits


WCAG & Section 508
Conform with Local and International Requirements


a11y.Radar
Ongoing Monitoring and Maintenance


Consultation & Training

Is Your Website Vulnerable to Frivolous Lawsuits?
Get a Free Web Accessibility Audit to Learn Where You Stand
Find Out Today!

Web Design & Development

Marketing

PPC Management
Google & Social Media Ads


Professional SEO
Increase Organic Search Strength

Interested in Marketing?
Speak to an Expert about marketing opportunities for your brand to cultivate support and growth online.
Contact Us

About

Blog

Contact Us
  • Buttons vs Links: Who Gets the Last Click?

    Buttons vs Links: Who Gets the Last Click?

    You’ve got a component to wire up and a design that looks like… a rectangle with text in it. Classic. Do you reach for <button> or <a>? For a mouse user, either might “work.” For a keyboard user or someone on a screen reader, the wrong choice is a booby trap. Picture a user pressing Space on something that looks like a button and nothing happens, or hearing “Link” and suddenly a file gets deleted. That gap between what an element promises and what it does is where trust dies. By the time you ship this, you should be able to look at any interactive element and decide between buttons vs links without second-guessing.

    The Rule Behind Buttons vs Links

    There’s one rule worth tattooing on your coding hand:

    Links go places. Buttons do things.

    If an interaction navigates to a new location (a different route, an external page, a same-page anchor, or a file), it’s a link. If it performs an action on the current page (submits, toggles, opens, closes, mutates UI, updates data), it’s a button. Keep that mental model tight and the rest—semantics, keyboard behavior, screen reader expectations—snaps into alignment.

    Let’s make that concrete. Screen readers announce name and role. “Link” tells the user to expect navigation; “Button” says “an action is about to happen.” Keyboard support follows suit: links activate with Enter; buttons activate with Enter and Space. That difference isn’t trivia—it’s the platform contract.

    Why This Tiny Decision Matters More Than It Looks

    First, semantics affects product quality. When the role and behavior match, users trust your interface—especially users who navigate by role (“jump me to the next button”). Second, robustness. A real link with a real href will still navigate if JavaScript takes a day off. A real button with type="submit" will submit the form without your custom event handlers. Getting buttons vs links right means your UI remains reliable under bad Wi-Fi, flaky extensions, or partial loads.

    And yes, standards. Mislabeling roles or breaking keyboard activation is how you wander into WCAG failures like 2.1.1 (Keyboard) or 4.1.2 (Name, Role, Value). It’s not about box-ticking; it’s about delivering predictable, testable behavior.

    When It Should Be a Button

    If the thing does something on this page, start with <button>. That covers submitting a form, opening a modal, toggling a menu, expanding an accordion, saving a record, deleting an item, starting a fetch, pausing media—anything that changes state without changing URL.

    Here’s what not to do:

    <!-- Wrong: Looks like a link, acts like a button, breaks expectations -->
    <a href="#" onclick="submitForm()">Submit</a>

    This announces as “link,” ignores the Space key unless you recreate that yourself, and fails if JavaScript is blocked. Use the element that already does the job:

    <!-- Right: Predictable, robust, testable -->
    <button type="submit">Submit</button>

    Toggles are another frequent offender. If you’re opening and closing a menu, use a button and reflect state:

    <button
      type="button"
      aria-expanded="false"
      aria-controls="mainmenu"
      id="menubutton">
      Menu
    </button>
    
    <nav id="mainmenu" hidden>…</nav>

    When you flip the menu, flip aria-expanded and manage the hidden attribute. Users get the correct announcement, and you get keyboard support for free.

    A quick style note while we’re here: don’t remove the focus outline unless you replace it with something obvious. Minimalism is lovely; invisible focus isn’t.

    button:focus-visible {
      outline: 2px solid currentColor;
      outline-offset: 3px;
    }

    When It Should Be a Link

    If the action navigates—new page, external site, file download, or a jump within the same page—reach for <a> with a real href. That gives you built-in affordances like “open in new tab,” a visible status bar URL, and the user’s browser history doing its thing.

    Bad pattern:

    <!-- Wrong: Navigation disguised as a button -->
    <button onclick="location='/about'">Learn more</button>

    Fix it:

    <!-- Right:  It’s navigation, so it’s a link -->
    <a href="/about">Learn more</a>

    A few patterns that absolutely belong to links:

    • Skip links: let keyboard users bypass repeating navigation.
     <a href="#main" class="skip-link">Skip to main content</a>
    <main id="main">…</main>
    • Downloads: if you can link it, link it.
     <a href="/report.pdf" download>Download report (PDF)</a>
    • Breadcrumbs and primary nav: always links. Users expect middle-clicks and new tabs to work.

    Give the link text meaning. “Click here” ages badly outside its paragraph. “Download Q3 report (PDF)” holds up wherever a user encounters it—like a screen reader’s Links List.

    Styling Without Lying: Buttons vs Links in Disguise

    Design will ask you to make links look like buttons or vice-versa. That’s fine visually, as long as the semantics don’t lie. If it navigates, keep it an <a>—then style it like a button. If it acts, keep it a <button>—then style it to match your theme. Users might not see the markup, but assistive tech will, and so will your QA.

    A few constraints worth honoring while you polish:

    • Don’t rely on color alone to signal “this is a link.” Underlines or a small icon are your friends.
    • Keep contrast sane (think 4.5:1 for normal text). Your future self, reading in sunlight, says thanks.
    • Targets should be comfortably tappable—around 44×44 CSS pixels is a good baseline.
    • Maintain a visible focus style. If you nuke it, put a better one back.

    Testing the Decision: Buttons vs Links Under Real Inputs

    Automated tools are a fast smoke test—Lighthouse or WAVE will happily rat out missing names, broken contrast, or off-screen focus. Treat them as lint for accessibility. They won’t catch intent.

    Intent is a manual game:

    • Screen reader pass: with VoiceOver (macOS/iOS), NVDA or JAWS (Windows), confirm elements announce the correct role and name: “Button, Submit,” not “Link, Submit.”
    • Keyboard pass: tab through. Links should activate with Enter; buttons with Enter and Space. Watch focus—no disappearing acts.
    • Voice control: say “Click Submit” or “Go to Pricing,” and make sure the right control responds by name.

    If any of those feel off, they are off. Fix the semantics first; the bugs usually evaporate.

    Real-World Fixes That Come Up in Code Reviews

    Most bugs we see with buttons vs links boil down to “we styled the wrong element” or “we tried to be clever with roles.” Two quick refactors cover a lot of ground:

    Submitting with an anchor:

    <!-- Wrong -->
    <a href="#" onclick="submit()">Submit</a>
    
    <!-- Right -->
    <button type="submit">Submit</button>

    Menu toggles built on anchors:

    <!-- Wrong -->
    <a href="#" onclick="openMenu()">Menu</a>
    
    <!-- Right -->
    <button type="button" aria-expanded="false" aria-controls="mainmenu">Menu</button>

    If you truly, absolutely must build a custom control—and you’ve checked that <button> won’t cut it—own the keyboard and state explicitly:

    <!--Only if native won’t work -->
    <div role="button" tabindex="0" aria-pressed="false" id="play">Play</div>
    <script>
    const el = document.getElementById('play');
    el.addEventListener('keydown', (e) => {
      if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); el.click(); }
    });
    el.addEventListener('click', () => {
      const next = el.getAttribute('aria-pressed') !== 'true';
      el.setAttribute('aria-pressed', String(next));
    });
    </script>

    That’s a lot of ceremony to re-implement what <button> just… does. Treat this as a last resort.

    A Short Checklist (Pin It Next to Your Linter)

    • Navigation? <a href="…">. Action? <button>.
    • Make the accessible name obvious: visible text or a clear aria-label.
    • Preserve expected keyboard behavior (Enter vs Enter+Space).
    • Keep focus visible and movement logical.
    • Prefer native elements; avoid role-swapping unless there’s no alternative.

    Wrapping It Up

    Interfaces are a web of tiny decisions, and this is one of the tiniest. But consistent, honest semantics make everything else easier: testing, maintenance, onboarding new devs, and—most importantly—using the thing. Treat buttons vs links as a contract. Say what the element is, and make sure it behaves that way across mouse, keyboard, screen readers, and voice.

    If you want a quick heuristic while you code: would a middle-click make sense here? If yes, it’s probably a link. Would “Click Submit” make sense to a voice user? If yes, it’s probably a button. Keep those instincts sharp and your UI will feel clean, resilient, and respectful by default.

    If your team wants a second set of eyes on patterns like these—or you need help pressure-testing components before they scale—216digital is happy to jump in. Schedule an ADA briefing and we’ll help you turn the “tiny” choices into durable, inclusive defaults.

    Greg McNeil

    September 16, 2025
    How-to Guides
    Accessibility, Accessible Buttons, Links, Web Accessibility, Web Accessible Links, web developers, web development, Website Accessibility
216digital Scanning Tool

Audit Your Website for Free

Find Out if Your Website is WCAG & ADA Compliant













    216digital Logo

    Our team is full of expert professionals in Web Accessibility Remediation, eCommerce Design & Development, and Marketing – ready to help you reach your goals and thrive in a competitive marketplace. 

    216 Digital, Inc. BBB Business Review

    Get in Touch

    2208 E Enterprise Pkwy
    Twinsburg, OH 44087
    216.505.4400
    info@216digital.com

    Support

    Support Desk
    Acceptable Use Policy
    Accessibility Policy
    Privacy Policy

    Web Accessibility

    Settlement & Risk Mitigation
    WCAG 2.1/2.2 AA Compliance
    Monitoring Service by a11y.Radar

    Development & Marketing

    eCommerce Development
    PPC Marketing
    Professional SEO

    About

    About Us
    Contact

    Copyright 2024 216digital. All Rights Reserved.