Those of us who have been doing web development for more years than we care to remember might consider that CSS Grid is a little bit like using “tables for layout”. Back in the early days of web design, the way we constructed page layout was to use HTML tables, then fragment our design into the cells of those tables in order to create a layout. This had some advantages over the “CSS Positioning” that came afterwards, in that we could take advantage of the alignment and full height columns offered by table display. The biggest downside however was that it tied our design to the mark-up, often creating accessibility issues as it did so. In order to lay the design out in the table we often broke up the content in ways that made no sense at all when read out by a screen reader for example.
In moving to CSS we often spoke about CSS for layout enabling a separation of content and markup and presentation. The ultimate aim being that we could create a semantic and well structured document, then apply CSS to create the layout we desired. Sites such as the CSS Zen Garden showcased this ability. The CSS Zen Garden challenged us to take identical markup and create a unique design using CSS.
CSS Grid Layout does not have the same issues that tables did, our grid structure is defined in CSS rather than in the mark-up. If we need to add an element we can use something with no semantic meaning. On paper grid helps us properly fulfill that promise of content separated from mark-up, however is it possible to go too far with this idea? Is it possible that we could create an accessibility issue through our use of grids?
We’ve already seen in these guides that grid gives us power to re-order the content of our page in various ways. We can use the order
property, which will change how items auto-place. We can use grid-auto-flow: dense
which will take items visually out of DOM order. We can also position items using line-based placement of grid template areas, without considering their location in the source.
The specification includes a section that covers Reordering and Accessibility. In the introduction to that section are details of what the specification expects browsers to do when the content is visually reordered using Grid Layout.
Grid layout gives authors great powers of rearrangement over the document. However, these are not a substitute for correct ordering of the document source. The order property and grid placement do not affect ordering in non-visual media (such as speech). Likewise, rearranging grid items visually does not affect the default traversal order of sequential navigation modes (such as cycling through links, see e.g. tabindex HTML5).
If you reorder things visually using grid layout, this will not change how the items are ordered if the content is being read out by a screen reader, or other text to speech user agent. In addition, the reordering will not change tab order. This means that someone navigating using the keyboard could be tabbing through links on your site and suddenly find themselves jumping from the top to the bottom of the document due to a reordered item being next in line.
The specification warns authors (the CSSWG term for web developers) not to do this reordering.
Authors must use order and the grid-placement properties only for visual, not logical, reordering of content. Style sheets that use these features to perform logical reordering are non-conforming.
What does this mean for designing with grid layout in practice?
Any time you reorder things with grid layout – or with flexbox – you only perform visual reordering. The underlying source is what controls things like text to speech, and the tab order of the document. You can see how this works with a very simple example.
In this example I have used grid to lay out a set of boxes that contain links. I have used the line-based placement properties to position box 1 on the second row of the grid. Visually it now appears as the fourth item in the list. However, if I tab from link to link the tab order still begins with box 1, as it comes first in the source.
.wrapper { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 100px; } .box1 { grid-column: 1; grid-row: 2; }
<div class="wrapper"> <div class="box box1"><a href="">One</a></div> <div class="box box2"><a href="">Two</a></div> <div class="box box3"><a href="">Three</a></div> <div class="box box4"><a href="">Four</a></div> <div class="box box5"><a href="">Five</a></div> </div>
The specification says that in this scenario, if box 1 really makes sense logically in that position, we should go back to our source and make the change there rather than reordering using grid layout. This is what is meant by visual versus logical reordering, logical ordering is important for the meaning and structure of our document, and we should make sure that we preserve that structure.
From the specification we know that we need to ensure our document maintains the logical order of our content. How should we approach our development to make sure that we maintain accessibility for the different users and the ways that they interact with our pages?
float
-based layout for example, where document source matters a lot in order to get layouts at different breakpoints. However the onus is on us as developers to remember to go back to our source and update it to maintain logical order.Another issue to be aware of in CSS Grid Layout and to a lesser extent in CSS Flexbox, is the temptation to flatten markup. As we have discovered, for an item to become a grid item it needs to be a direct child of the grid container. Therefore, where you have a <ul>
element inside a grid container, that ul
becomes a grid item – the child <li>
elements do not.
If the subgrid
value of display
becomes implemented, it would be possible to make these children of a grid item participate in the overall grid layout by declaring the ul
element a subgrid. Currently the only way to do this is to use display: contents
to cause the box generated by the ul
to disappear from the DOM. For more information about this interaction see the guide on the Relationship of Grid Layout to other layout methods and the section on display: contents
.
Given that interoperable support for display: contents
is limited and we do not yet have subgrids, there is a definite temptation when developing a site using CSS Grid Layout to flatten out the markup, to remove semantic elements in order to make it simpler to create a layout. An example would be where some content was semantically marked up as a list but you decide to use a set of <div>
elements instead as then you can have the element to be a direct child of a container set to display: grid
. Be aware of this temptation and find ways to develop your design without stripping out the markup. Starting out with a well-structured document is a very good way to avoid the problem, as you will be aware that you are removing semantic elements in order to make the layout work if you actually have to go into the document and do so!
There is not a lot of existing material regarding accessibility and CSS Grid Layout. Many of the issues are similar to those raised regarding CSS Flexbox, which also gives methods of reordering content with flex-direction
and the order
property.
The concept of visual display following document source order is detailed in the WCAG Techniques for Success Criteria – Technique C27.
As a way to start thinking about these issues, as you use CSS Grid Layout I would suggest reading Flexbox & the Keyboard Navigation Disconnect from Léonie Watson. Also the video of Léonie’s presentation from ffconf is helpful to understand more about how screen readers work with the visual representation of things in CSS. Adrian Roselli has also posted regarding tab order in various browsers – although this was prior to grid support being fully implemented in Firefox.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_Layout_and_Accessibility