Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

WCBuf: CSS Display Properties versus HTML Semantics


Published on

Many (most?) developers make the effort to choose HTML elements that best describe the structure and semantics of the content. They then use CSS to set the layout for the visual design. What they don’t know is how browsers use that CSS to break the HTML semantics. I will demonstrate issues and offer unfortunate workarounds.

Published in: Technology
  • Relationship guru Justin Sinclair reveals his secret tactics to help get your Ex back! Learn how ■■■
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

WCBuf: CSS Display Properties versus HTML Semantics

  1. 1. CSS Display Properties versus HTML Semantics Presented at WordCamp Buffalo 2018 Slides will be posted at
  2. 2. • I’ve written some stuff, • Member of W3C, • Building for the web since 1993, • Learn more at, • Avoid on Twitter @aardrian. About Adrian Roselli
  3. 3. HTML Tables
  4. 4. HTML Tables • We will use HTML tables as our proxy, • They have a long history on the web, • Used for layout and tabular data, • Have a specific DOM structure, • Have their own navigation features in assorted tools.
  5. 5. Basic HTML Table • Just make a valid HTML <table>. • Avoid spanning cells, • Make sure you use <th> for headers, • Add a useful <caption>.
  6. 6. Basic HTML Table <table> <caption>Books I May or May Not Have Read</caption> <tr> <th>Author</th> <th>Title</th> <th>Year</th> </tr> <tr> <td>Miguel De Cervantes</td> <td>The Ingenious Gentleman Don Quixote of La Mancha</td> <td>1605</td> </tr> […] <tr> <td>George Orwell</td> <td>Nineteen Eighty-Four</td> <td>1948</td> </tr> </table>
  7. 7. Complexity #1: Row Headers • Continue to use <th>, • Add the scope attribute using the values (as appropriate): • row, • col, • rowgroup, • colgroup. • Conforms to WCAG technique H63: Using the scope attribute to associate header cells and data cells in data tables.
  8. 8. Complexity #1: Row Headers <table> <caption>Contact Information</caption> <tr> <td></td> <th scope="col">Name</th> <th scope="col">Phone#</th> <th scope="col">Fax#</th> <th scope="col">City</th> </tr> <tr> <td>1.</td> <th scope="row">Joel Garner</th> <td>412-212-5421</td> <td>412-212-5400</td> <td>Pittsburgh</td> </tr> […] </table>
  9. 9. Complexity #2: Spanning Cells • Continue to use <th>, • Every <th> gets an id, • Every <td> gets a headers attribute • The headers value is the id of the <th> you want it to use, • Conforms to WCAG 2.0 technique H43: Using id and headers attributes to associate data cells with header cells in data tables.
  10. 10. Complexity #2: Spanning Cells <table> <tr> <th rowspan="2" id="h">Homework</th> <th colspan="3" id="e">Exams</th> <th colspan="3" id="p">Projects</th> </tr> <tr> <th id="e1" headers="e">1</th> <th id="e2" headers="e">2</th> <th id="ef" headers="e">Final</th> <th id="p1" headers="p">1</th> <th id="p2" headers="p">2</th> <th id="pf" headers="p">Final</th> </tr> <tr> <td headers="h">15%</td> <td headers="e e1">15%</td> <td headers="e e2">15%</td> <td headers="e ef">20%</td> <td headers="p p1">10%</td> <td headers="p p2">10%</td> <td headers="p pf">15%</td> </tr> </table>
  11. 11. RWD (Responsive Web Design)
  12. 12. Responsive Tables • Specifically talking about viewport width, • Just let it scroll off-screen: • Add tabindex="0" for keyboard users, • Add role="region“ so screen readers announce it, • Add aria-labeledby so screen readers give it a name, • Set the aria-labeledby value to the id of the <caption>.
  13. 13. Responsive Table <div role="region" aria-labeledby="Cap1" tabindex="0"> <table> <caption id="Cap1">Books I May or May Not Have Read</caption> <tr> <th>Author</th> <th>Title</th> <th>Year</th> <th>ISBN-13</th> <th>ISBN-10</th> </tr> <tr> <td>Miguel De Cervantes</td> <td>The Ingenious Gentleman Don Quixote of La Mancha</td> <td>1605</td> <td>9783125798502</td> <td>3125798507</td> </tr> […] <tr> <td>George Orwell</td> <td>Nineteen Eighty-Four</td> <td>1948</td> <td>9780451524935</td> <td>0451524934</td> </tr> </table> </div>
  14. 14. Even More Responsive (still tables)
  15. 15. Respond to Print
  16. 16. Respond to Windows High Contrast Mode
  17. 17. Respond to Viewport Width
  18. 18. Rejiggering the Layout @media screen and (max-width: 37em), print and (max-width: 5in) { table, tr, td { display: block; } […] td { display: grid; grid-template-columns: 4em auto; grid-gap: 1em 0.5em; } }
  19. 19. Rejiggering the Layout
  20. 20. CSS Display Properties
  21. 21. CSS Display Properties • The following override native semantics in the browser: • display: block • display: inline • display: grid • display: flex • display: contents • Nothing in the HTML / CSS specifications mandates this, • Does not work in reverse: • display: table • display: table-cell
  22. 22. Assistive Technology (AT) • Browsers do not convey correct semantics to AT, • Users who rely on these semantics can be stranded: • Understanding content, • Navigating a page.
  23. 23. Screen Reader (NVDA / Firefox)
  24. 24. Screen Reader (NVDA / Firefox)
  25. 25. Accessibility Tree • A sub-set of the DOM tree, • Includes UI objects of browser & objects of the document, • Created in tree for every DOM element that: • Fires an accessibility event, • Has a property, relationship or feature which needs to be exposed.
  26. 26. Accessibility Tree: <table>
  27. 27. Accessibility Tree: <caption>
  28. 28. Accessibility Tree: <th>
  29. 29. Accessibility Tree: <td>
  30. 30. ARIA to the Rescue? (Accessible Rich Internet Applications)
  31. 31. ARIA Table Roles • You can use ARIA to re-insert the lost semantics: • <table role="table"> • <thead|tbody|tfoot role="rowgroup"> • <tr role="row"> • <td row="cell"> • <th scope="col" role="columnheader"> • <th scope="row" role="rowheader"> • Cannot address re-ordered content, • Cannot address hidden content.
  32. 32. ARIA Table Roles • Do not use ARIA grid roles, • Test with a screen reader, • If your tables are generated from script, update the script.
  33. 33. Table with ARIA <table id="Books" role="table"> <caption id="Cap1">Books I May or May Not Have Read</caption> <tr role="row"> <th role="columnheader">Author</th> <th role="columnheader">Title</th> <th role="columnheader">Year</th> <th role="columnheader">ISBN-13</th> <th role="columnheader">ISBN-10</th> </tr> <tr role="row"> <td role="cell">Miguel De Cervantes</td> <td role="cell">The Ingenious Gentleman Don Quixote of La Mancha</td> <td role="cell">1605</td> <td role="cell">9783125798502</td> <td role="cell">3125798507</td> </tr> […] <tr role="row"> <td role="cell">George Orwell</td> <td role="cell">Nineteen Eighty-Four</td> <td role="cell">1948</td> <td role="cell">9780451524935</td> <td role="cell">0451524934</td> </tr> </table>
  34. 34. Screen Reader (NVDA / Firefox)
  35. 35. ARIA Grid
  36. 36. ARIA Grid • Do not use for simple data tables, • Intended to mimic Excel-style spreadsheet, • A grid is a composite widget so it: • Always contains multiple focusable elements, • Has only one focusable element in the page tab sequence, • Requires the author to provide code that manages focus movement inside it. • Ignoring for the purpose of this talk.
  37. 37. How Is This a Thing?
  38. 38. Assistive Tech Is Not at Fault • Not screen readers’ fault, • Accessibility information comes from browser, • Screen reader needs more than DOM to understand page, • Cannot ignore all but the DOM, • Years of HTML tables for layout informed screen readers, • Screen readers developed their own heuristics for dealing with tables.
  39. 39. Detecting AT Is Not Viable • Users don’t want us to be able to detect screen readers, • Not all screen reader users are blind anyway, • Mouse actions are a poor proxy for sighted screen reader users, • Disabling a site’s CSS for screen reader users is therefore impractical (and a terrible, terrible idea).
  40. 40. CSS Is Not Blameless • CSS already impacts HTML semantics — display: none, • Using display: table does not impart HTML table semantics, • CSS flex or grid makes it easy for content order and source order to disagree, • CSS grid to lay out an HTML table still won’t be a table semantically.
  41. 41. ARIA Is Not Ideal • You must understand ARIA and the table structure, • This will require you to keep current on screen reader and browser support, • You have to manage headers and other content you might hide, • Consider how this scales with CSS does not load, • This is not the purpose of ARIA, • The technique here is a stop-gap.
  42. 42. The Browser Is Not Right • The CSS spec does not state that semantics should be dropped, • As display properties, there is no reason to remove them, • The accessibility tree should not care about visuals.
  43. 43. CSS Rotation
  44. 44. Specific to Tables • Only works with tables with tiny data, • Keyboard navigation can be confusing, • You have to re-rotate contents, • There may be some mirroring involved, • Generally not a good idea.
  45. 45. Beware display: contents
  46. 46. What is display: contents • The element does not generate any boxes, • Its children and pseudo-elements still generate boxes, • Text runs as normal, • For box generation & layout, element treated as if replaced in element tree by its contents, • As if opening and closing tags removed, • Also yanks it from accessibility tree.
  47. 47. Why display: contents Is More Dangerous • You cannot add it back to the accessibility tree with ARIA, • You can give it an accessible name and properties, • But these are not passed to screen readers, • Browsers do not hand the information off, • If used as a poor-dev’s CSS reset: • Will hide elements from assistive technology, • Will hide semantics from assistive technology.
  48. 48. Affecting Different Elements
  49. 49. Accessibility Tree: <table>
  50. 50. Accessibility Tree: <ul>
  51. 51. Accessibility Tree: <button>
  52. 52. Accessibility Tree: <h2>
  53. 53. Screen Reader (NVDA / Firefox)
  54. 54. Bugs! • Firefox bug 1455357: Setting grid item to display:contents resets its accessible role • Chromium Issue 835455: Element not exposed to accessibility tree when it is set to display: contents • Safari bug 39630240 (which I cannot see because my AppleID may not have the needed permissions to see it) • CSSWG #2632: [css-display][css-aam][selectors-4] How elements with `display:contents` get focused?
  55. 55. Wrap-up
  56. 56. References • It’s OK to Use Tables • Hey, It’s Still OK to Use Tables • A Responsive Accessible Table • Tables, CSS Display Properties, and ARIA • Tables, JSON, CSS, ARIA, RWD, TLAs… • GitHub Contributions Chart • Short note on what CSS display properties do to table semantics by Steve Faulkner • Data Tables by Heydon Pickering • How display: contents; Works by Ire Aderinokun • CSS3 — Appendix B: Effects of display: contents on Unusual Elements
  57. 57. CSS Display Properties versus HTML Semantics Presented at WordCamp Buffalo 2018 Slides will be posted at