• 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

Shop phones

<h2 class="h-bravo">Shop phones</h2>
<ul class="product-list">
  <li class="product-list-item">
    <div class="offer-container">
      <button type="button" class="tertiary" aria-label="Save $400 with offer for mPhone Universe Max Extra Phabulous">
        Save $400 with offer
      </button>
    </div>

    <div class="link-container">
      <!-- The link DOES NOT wrap the entire description -->
      <h3 class="product-heading">
        <a class="product-link" href="/demos/">
          <span class="brand">
            mPhone
          </span>
          <span class="product-title">
            Universe Max Extra Phabulous
          </span>
        </a>
      </h3>
      <div class="product-image-container">
        <img class="product-image" src="/assets/images/products/mobile-phone.png" alt="mPhone Universe Max Extra Phabulous"/>
      </div>
      <ul id="meta" class="product-meta">
        <li class="rating">4.8 Stars</li>
        <li class="network">7G <span class="hidden">network compatibility</span></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 class="button" aria-hidden="true">
        See details
      </div>
    </div>
  </li>


  <li class="product-list-item">
    <div class="offer-container"></div>
    <div class="link-container">
      <!-- The link DOES NOT wrap the entire description -->
      <h3 class="product-heading">
        <a class="product-link" href="/demos/">
          <span class="brand">
            mPhone
          </span>
          <span class="product-title">
            Universe Max Sorta Phabulous
          </span>
        </a>
      </h3>
      <div class="product-image-container">
        <img class="product-image" src="/assets/images/products/mobile-phone.png" alt="mPhone Universe Max Sorta Phabulous"/>
      </div>
      <ul id="meta" class="product-meta">
        <li class="rating">4.8 Stars</li>
        <li class="network">6G <span class="hidden">network compatibility</span></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 class="button" aria-hidden="true">
        See details
      </div>
    </div>
  </li>

  <li class="product-list-item">
    <div class="product-group-container" role="group" aria-label="Phone">
      <div class="offer-container">
        <button type="button" class="tertiary" aria-label="Save $400 with offer for mPhone Universe Not So Phabulous">
          Save $100 with offer
        </button>
      </div>

      <div class="link-container">
        <!-- The link DOES NOT wrap the entire description -->
        <h3 class="product-heading">
          <a class="product-link" href="/demos/">
            <span class="brand">
              mPhone
            </span>
            <span class="product-title">
              Universe Not So Phabulous
            </span>
          </a>
        </h3>
        <div class="product-image-container">
          <img class="product-image" src="/assets/images/products/mobile-phone.png" alt="mPhone Universe Not So Phabulous"/>
        </div>
        <ul id="meta" class="product-meta">
          <li class="rating">4.8 Stars</li>
          <li class="network">2G <span class="hidden">network compatibility</span></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 class="button" aria-hidden="true">
          See details
        </div>
      </div>
    </div>
  </li>
</ul>