• How to Keep Your CSS Grid Layouts Accessible
  • Written by Anna Monus
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: EmilyQiRabbit
  • Proofreader: Xionglong58, Hanxiansen

A CSS Grid can place elements into a Grid with rows and columns, making it possible to create a two-dimensional layout. With it, you can customize any shape of the grid, such as the width and height of the grid, the range of grids, or the gaps between grids. However, CSS Grids can have poor accessibility issues, especially for those who use screen readers and only keyboards. This tutorial will help you avoid such problems.

Source sequence independence

Source order independence is one of the great advantages of CSS Grid. This means that you don’t need to define the layout structure in HTML as you would with float or table layouts. You can change the visual appearance of the HTML rendering using the sorting and Grid position properties of the CSS Grid.

The REordering and Accessibility section of the CSS Grid document of the W3C defines source order independence as:

“By combining grid layouts with media queries, developers can use the same semantic markup, but the rearrangement of element layouts is independent of the source code order, allowing the desired layout to be achieved in both source code order and rendered visuals.”

With CSS Grid, you can decouple the logical order from the visual order. Source order independence is useful in many cases, but it can also break the accessibility of code. Users using screen readers and keyboards can only see the logical order of your HTML files, but not the visual order created by the CSS Grid.

This is usually not a big deal if your documentation is simple, because the logical and visual order of the source code is basically the same. However, documents that are complex, asymmetrical, fragmented, or use other creative layouts can often be confusing to users of a screen reader or keyboard.

A property that changes the order of vision

The CSS Grid has a number of properties that can change the visual order of documents:

  • Order – Has the order attribute in both flexbox and CSS Grid rules. It can change the default ordering of items in flex or Grid containers.
  • Grid position attributes — grid-row-start, grid-row-end, grid-column-start, grid-column-end.
  • Shorthand for the grid position property above —grid-row.grid-column, andgrid-area(it isgrid-row 和 grid-columnShort for “.
  • Grid-template-areas – Specifies the locations of named grid areas.

If you want to know more about the use of grid location attributes, check out our previous article on grid regions. Now, let’s look at how visual reordering can cause code accessibility problems.

Visual and logical reordering

This is a simple grid layout with just a few simple links, so you can test the code using the keyboard:

<div class="container">
    <div class="item-1"><a href="#">Link 1</a></div>
    <div class="item-2"><a href="#">Link 2</a></div>
    <div class="item-3"><a href="#">Link 3</a></div>
    <div class="item-4"><a href="#">Link 4</a></div>
    <div class="item-5"><a href="#">Link 5</a></div>
    <div class="item-6"><a href="#">Link 6</a></div>
</div>
Copy the code

Now let’s add some more styles. The CSS code below puts grid elements into three columns of the same width. Using the grid-row attribute, the first element is moved to the beginning of the second row.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 0.625 rem;
}
 
.item-1 {
  grid-row: 2;
}
Copy the code

In the figure below, you can see the final visual, with Link 1 styled to highlight it. Normal users will see Link 2 first, but screen readers will start with Link 1 because they follow the logical order defined in the HTML code.

For keyboard-only users, TAB browsing is also difficult because it still starts at Link 1, the bottom left corner of the page (try it yourself).

The solution

The solution is very simple and elegant. Don’t change the visual order, just move Link 1 to the bottom of the HTML file. In this way, the source order and visual order are consistent.

<div class="container">
  <div class="item-2"><a href="#">Link 2</a></div>
  <div class="item-3"><a href="#">Link 3</a></div>
  <div class="item-4"><a href="#">Link 4</a></div>
  <div class="item-1"><a href="#">Link 1</a></div>
  <div class="item-5"><a href="#">Link 5</a></div>
  <div class="item-6"><a href="#">Link 6</a></div>
</div>
Copy the code

You don’t need to add any Grid attributes to the.item-1 CSS. Since you don’t have to change the default source code order either, you just need to define the properties for the grid container.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 0.625 rem;
}
Copy the code

See, even though this example ended up the same as before, it’s now much more accessible. Using a TAB or screen reader starts with Link 2 and logically follows source code order.

How can I make my layout more accessible

Here are a few general layout templates that you can use to make code that uses CSS Grid to reorder properties more accessible. For example, the “Holy Grail layout” is one such pattern. It consists of a header, a main content area, a footer, and two fixed-width sidebars, one on the left and one on the right.

The left-hand column layout can be confusing for screen readers. This is because the left column is in the source code order before the main content area, and it is the first thing the screen reader sees. However, in general, it is best for screen readers to start reading from the main content. Especially if the left side contains ads, blog catalogs, tag clouds, and other irrelevant content.

CSS Grid allows you to change the source order of your HTML files and place the main content in front of two sidebars:

<div class="container">
    <header>Header</header>
    <main>Main content</main>
    <aside class="left-sidebar">Left sidebar</aside>
    <aside class="right-sidebar">Right sidebar</aside>
    <footer>Footer</footer>
</div>
Copy the code

There are other solutions available to define visual order changes using CSS Grid. Most tutorials use named grid areas and rearrange them using the grid-template-Areas attribute.

The following code is the simplest solution, as it simply adds a few additional rules for elements that differ in visual and source order. The CSS Grid has an excellent auto-arrangement feature that takes care of the remaining Grid elements.

.container {
  display: grid;
  grid-template-columns: 9.375 rem 1fr 9.375 rem;
  grid-gap: 0.625 rem;
}
header.footer {
  grid-column: 1 / span 3;
}
.left-sidebar {
  grid-area: 2 / 1;
}
Copy the code

Grid-column makes the

and

areas span the entire screen (three columns), and grid-area (short for grid-row and grid-column) fixes the left column. Here’s what it looks like using these styles:

Although the Holy Grail layout is a relatively simple layout, you can use the same logic for some more complex layouts. Always keep in mind which parts of the page are the most important and which are the most likely to be looked at by a screen reader user before anything else.

What to do about semantic loss

In some cases, CSS grids can also be semantic wreckers; This is also an area that affects accessibility. Due to the display: the grid; The layout is inherited only by the immediate children of the element, and the children of the grid element are not actually part of the grid layout. To save effort, developers may decide that flattening the layout is a good solution, so they make all the elements they want to include in the grid layout as direct children of the grid container. However, if a layout is perceived to be flat, the semantics of the file are often lost.

Add that you want to create an exhibition wall of elements (such as a picture wall), where elements are arranged in a grid surrounded by a header and a footer. Here’s how to write a tag with semantics:

<section class="container">
    <header>Header</header>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
        <li>Item 6</li>
    </ul>
    <footer>Footer</footer>
</section>
Copy the code

But if you want to use CSS Grid,

should be used as Grid containers, and < H1 >, < H2 >, and

    are Grid elements. However, the elements in the list are not included in the grid because they are children of the grid container’s children.

So, if you want to get things done quickly, it might be a good idea to flatten the layout structure so that all elements are children of the grid container:

<section class="container">
    <header>Header</header>
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item">Item 5</div>
    <div class="item">Item 6</div>
    <footer>Footer</footer>
</section>
Copy the code

Now you can easily create your desired layout using CSS Grid:

.container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 0.625 rem;
}
header.footer {
    grid-column: 1 / span 3;
}
Copy the code

Everything looks fine, but the document has lost its original semantics, so:

  • Users of screen readers have no way of knowing the relationships between elements or that they are actually part of a list (most screen readers inform the user of the number of list elements).
  • Broken semantics can also make it difficult for search engines to understand your content;
  • If users access your content with CSS disabled (for example, when the Internet speed is poor), they may be confused when browsing the page because all they see is a series of unrelated divs.

The most important rule is that you must never give up semantics to look good.

The solution

Current solutions create nested grids by adding CSS rules to unsorted lists.

.container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 0.625 rem;
}
.container > * {
    grid-column: 1 / span 3;
}
ul {
    display: inherit;
    grid-template-columns: inherit;
    grid-gap: inherit;
}
Copy the code

In the following example, you can see how the nested grid is related to the parent grid. The elements are arranged as expected, but at this point, the document retains its semantics.

conclusion

A simple CSS Grid layout probably won’t cause accessibility problems. But when you want to change the visual order or create a multi-layer grid, problems can come to the surface. Fixing these issues is usually trivial, so it’s worth it to fix accessibility issues so that you can make your content more readable to users using accessibility tools.

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.