• When the user clicks a link, they are taken to a different location in the site.
    • Either another page or even another area of the same page
  • A link can look like a big shiny button but it must be coded as <a> link

If it does something, it’s a <button>

  • Buttons cause an action to occur on the same page
    • Submit a form (even when submission takes you to a new page)
    • Open a menu
    • Launch a modal
    • Expand details
  • A button can look like a link, but it must be coded as a <button>

Code examples

Use semantic HTML with common sense names

This semantic HTML contains all accessibility features by default.

<a href="/about/">
  About
</a>
About
  • Do not use a heading with a generic link below.
  • Instead, make the heading a link.
<h3>About our coffee subscriptions</h3>
<p>Get the best coffee delivered to your door</p>
<a href="/about/">
   Learn more
</div>

If a link has no definable url, add tabindex="0" to make it focusable.

  • A link with no href will not be focusable with the keyboard.
  • Do not put anything but a URI in the href
<a tabindex="0">
  About
</a>
About

Avoid custom elements

This custom button requires extra attributes and keyboard event listeners.

<custom-element role="link" tabindex="0">
  About
</custom-element>

Sometimes the design will call for multiple links with the same text label. In a case like this, aria-label can be used to name each link’s purpose.

<button>Get free coffee</button>
<a href="/free-coffee-tc/" aria-label="Free coffee terms and conditions">
  Terms &amp; Conditions
</a>
<button>Get free donuts</button>
<a href="/free-donuts-tc/" aria-label="Free donuts terms and conditions">
  Terms &amp; Conditions
</a>

Don’t duplicate the visible text name in the aria-label

Do not repeat the inner text content of a link in the aria-label.

<a href="/do-NOT-repeat-yourself/" 
   aria-label="Do NOT repeat yourself">
   Do not repeat yourself
</div>

Don’t use javascript in href

  • Do not use "href="javascript:void(0)".
  • When screen readers read the href, it becomes confusing and nonsensical
<a href="javascript:void(0)">
   Do not use javascript in href
</div>

Don’t use “#” in href

<a href="#">
   Do not use # to populate the href
</div>

Complex examples

  • Don’t wrap large blocks of content or nest other interactive components inside a link.
  • This complex example uses a simple link and references product information using aria-describedby
  • This allows the link to be read first (without the repetition of the image alt text) and then the screen reader will read the related product information (colors, pricing).
  • The HTML is written in logical order for the screen reader and CSS grid layout is used to re-arrange the elements visually.
  • No Javascript is used, this example uses well supported CSS only techniques
<ul class="product-list">
  <div class="product-list-item">
    <button type="button" class="tertiary" aria-label="Save $400 with offer for NoPhone Universe Max Extra Phabulous">
      Save $400 with offer
    </button>
    <div class="link-container">
      <!-- The link DOES NOT wrap the entire description -->
      <a class="product-link" href="/demos/" aria-describedby="meta colors pricing">
        <span class="brand">
          mPhone
        </span>
        <span class="product-title">
          Universe Max Extra Phabulous
        </span>
      </a>
      <div class="product-image-container">
        <img class="product-image" src="/assets/images/products/mobile-phone.png" alt="NoPhone Universe Max Extra Phabulous"/>
      </div>
      <ul id="meta" class="product-meta">
        <li class="rating">4.8 Stars</li>
        <li class="network">5G</li>
      </ul>
      <ul id="colors" class="product-colors">
        <li class="red"><span class="hidden">Sunset Red</span></li>
        <li class="gold"><span class="hidden">Golden Canyon</span></li>
        <li class="blue"><span class="hidden">Blue</span></li>
        <li class="gray"><span class="hidden">Graphite</span></li>
      </ul>
      <ul id="pricing" class="product-pricing">
        <li class="monthly">
          <div><strong>Monthly</strong></div>
          <strong>
            $22.00<span class="hidden">,</span>
          </strong>
          <span class="hidden">
            Original price:
          </span>        
          <s>$50.00</s>
          <div>For 36 months</div>
        </li>
        <li class="today">
          <div><strong>Today</strong></div>
          $0
          <div>down + tax</div>
        </li>
        <li class="full-price">
          <strong>Full price</strong> $1,789<span class="hidden">,</span>
          <span class="hidden">
            Original price:
          </span>        
          <s>$1,998</s>
        </li>
      </ul>
    </div>
  </div>
</ul>