Skip to content
grid

CSS Grid and Accessibility

November 4, 20192 min readCSS Grid, Accessibility
Source: Vecteezy

Introduction of CSS Grid Layout is the best addition in modern css, it help us build more complex layout designs using a two-dimensional way, using both rows and columns.

While it solves complex layout design and opens new path for implementing any sort of design layouts across devices (laptop, large desktop, tablet, phone, phablet etc…). But at the same time incorrect implementation leads to accessibility issues for keyboard users and screen readers. Let’s dive straight into it.

Visual vs. Logical Reordering

While CSS Grid enables reordering of content in various ways, but it should only be used for visual, not logical reordering of content. Here is an example of simple grid consist of 2 rows and 3 columns, both have common markup but different output based on styling:

  • First one is correct order of grid
  • While second is tweaked with grid-row property

These columns have link, so visually user will see 4th link in 1st row, but screen readers and keyboard user will encounter problem, as tabbing will jump to 3rd link in 2nd row then back to 4th link on 1st row.

Solution

Well solution is simple and elegant, just move 4th link in markup after 2nd and it will not be an issue any more. Below you can see code in action as well:

Codesandbox

Flat markup vs. Semantic markup

Well CSS Grid solves lot of problems, but one should be extra careful while writing markup. To create a grid all items should be direct child of container, any items which are not direct child will not inherit display: grid property.

So what happens next is, when some developer wants to create grid structure there may need arise to flatten out markup for whatever reason but it will break semantic meaning of layout and leads to accessibility issues. Let’s take a classic example of header layout consist of logo and navigation links.

Below are the sample code snippets of flatten markup and semantic markup

Code Snippets

Flatten-Markup
  <header class="grid-container">
    <a href="#" class="logo">
      <img src="https://logoipsum.com/logo/logo-10.svg">
    </a>
    <a href="#" class="nav-link">Home</a>
    <a href="#" class="nav-link">About</a>
    <a href="#" class="nav-link">Services</a>
    <a href="#" class="nav-link">Contact</a>
  </header>

Lost semantic

Here comes the real issue with flatten markup and it will cause huge inconvenience to screen reader users, as there is no to communicate presence of navigation in it. It will announce flat links in header.

The correct approach

Using right semantic structure, we can achieve desired output as well as make things easier for screen reader users. Below markup in snippet is slightly different from above with right native HTML tags. Now screen reader will announce navigation with multiple list items of links.

Semantic-Markup
  <header class="grid-container grid-container-semantic
  grid-container--three">
    <a href="#" class="logo">
      <img src="https://logoipsum.com/logo/logo-10.svg">
    </a>
    <nav class="top-nav top-nav--semantic">
      <ul>
        <li><a href="#" class="nav-link">Home</a></li>
        <li><a href="#" class="nav-link">About</a></li>
        <li><a href="#" class="nav-link">Services</a></li>
        <li><a href="#" class="nav-link">Contact</a></li>
      </ul>
    </nav>
  </header>

You can see how both markup are slightly different, but desired output can be achieved using CSS Grid. See it in action:

Codesandbox

So, note to self always use semantic markup over flatten markup, though later one saves your time or say it will double your work, once you think of accessibility and decides to re-write it.

Powered by