Which CSS properties affect the accessibility tree?
Asked Answered
J

3

5

By the sacred separation of contents and presentation, I assumed that CSS was ignored by screen readers. This naive assumption is false.

  • It appears that many ways of hiding contents from CSS, such as display:none; or visibility:hidden; or even width:0; height:0;, remove the hidden element from the accessibility tree. Their contents are not focusable e.g. via the tab key, and invisible to screen readers.

    [ Aside: Accessibility often requires hiding elements while keeping them accessible to screen readers: e.g. for skip links, alternative text, or a show/hide mechanism which only makes sense when using a screen. To actually do that, you need CSS trickery, such as moving the element off-screen by a large margin. Apparently these are commonly agreed methods, used and advocated by WebAIM and MDN. Also look at the CSS of the skip link on the result page of Google Search, for instance. ]

  • I also found that text added via the content property, often used to attach decorative characters ::before or ::after an element, does appear in the accessibility tree (to me, Firefox shows it as “static text”).

    [ Aside: This is often undesired as the added text consists of meaningless characters which happen to render as visually nice symbols, with the adequate font. ]

My question is in the title: which CSS properties (or values) affect the accessibility tree?

Of course CSS, as it governs presentation, matters for most visual impairments (dyslexia, myopia, all kinds of color blindness… or for anyone really). But I did not expect that CSS also matters for blind users. I thought that only the semantic contents given by HTML was important to them, and that the accessibility tree was built solely from HTML.

Jonas answered 3/5, 2021 at 14:38 Comment(1)
The AOM (Accessibility Object Model) is a subset of the DOM and so any class that removes an element from the DOM will most likely remove it from the AOM as well. A good article here: developer.mozilla.org/en-US/docs/Learn/Accessibility/…. Basically don't display: none elements that need to be read, and don't style html for a purpose other than what they were made for (like using a div as a button). Semantic HTML is a great place to start (check it!) and no aria label is better than a bad one.Ringnecked
B
4

Properties that matter:

Visibility

CSS regarding visibility is picked up by screen readers as it is assumed you do not want people interacting with this item if it is not visible. Otherwise an entire section that is hidden from "sighted users" would be visible to screen reader users and offer them a different experience. For example:

  • display: none - universal support, if an element has this property it is assumed you do not want anyone seeing it.
  • visibility: hidden - same but some really older screen readers may pick this up still
  • opacity: 0 - not as effective as some screen readers may still pick this up but most will ignore.
  • visibility: collapse - use on tables, not sure how well supported it is but it should be interpreted as visibility: hidden by the browser (and therefore by the accessibility tree)

Size

If something is 0px tall or 0px wide it is not visible. For this reason the same rule is applied that if "sighted users" can't see it then screen reader users do not want to see it either.

Content property

This one is really inconsistent across different browser and screen reader combinations. You may see it in the accessibility tree but it does not mean that it will be used by the screen reader.

The thing is that technically screen readers should read the content.

Now because we as developers have used this for loads of styling tricks they have now improved the content property to have alt text. It only has 70% browser support at the moment and screen reader support will be even worse but eventually that problem will fix itself.

To get ahead of the curve on this all you need to do is add a slash between the displayed content and the alt text:

.myClass:after{
    content: "❤" / "favourited item";
}

CSS positioning

Technically this is kind of the opposite, where CSS is used to change the visual design (and make it logically ordered) but the DOM order is incorrect.

So although this one isn't quite a CSS affecting the accessibility tree item, it is closely related in such a way I thought I would mention it.

If you use CSS grid and change the positions of grid items you may end up with the DOM order being 1,2,3 but the visual order being 2,1,3.

Now if the logical reading order is 2,1,3 that can be super confusing for screen reader users as everything is read in the wrong order.

The same principle applies to float: right and flex-direction: reverse.

Negative margins can also cause some issues. For example be careful with margins when trying to visually hide text (when you mentioned about screen reader only text) - some browsers actually tried to correct for negative margins and meant that things were read out of order.

I would suggest reading this answer if you are looking for the current best practice on visually hiding things for screen reader users only!

Conclusion

I think that is it, but there could be others I haven't thought of.

In essence the reason CSS "leaks" into HTML here is because of how CSS affects what content is on the page and one core idea behind accessibility is "provide as similar experience / information as possible to people using assistive technology".

Surprisingly things like transform, backface-visibility: hidden; etc. do not seem to have any effect on screen readers, but I couldn't find anything in the spec that says whether they should or they shouldn't affect the accessibility tree and my tests were limited!

Finally I put "sighted users" in quotes as a lot of screen reader users have reasonable vision, some have perfect vision and use one to aid comprehension, it is just easier to compare "sighted" and "non sighted" when explaining the principles.

Beam answered 3/5, 2021 at 19:46 Comment(2)
The thing is that technically screen readers should read the content. ==> it's debattable. I can argue that since it's in CSS, it's decorative content only and so shouldn't be read.Eigenvalue
Oh I reread what I wrote, I can see where I wasn't clear. According the the user agent spec content should be added to the accessibility tree, but obviously according to WCAG (and with common sense) it shouldn't be used for important information as some people don't have CSS enabled / their own style sheets. Personally I don't think it should be used for any information at all and should be purely decoration, but we have to move with the times and patch bad habits so browsers must parse the alt part of the content attr as part of the DOM now (so it can be in the accessibility tree).Beam
T
2

It's worth noting these behaviors are highly dependent on browser implementation. They will not be true for every browser / screen-reader combination. Screen reader behavior can vary widely between products.


  • The background-image property: when given an image URL is not visible to screen readers, as there is no way to add alt-text.

  • The clip-path property: can be used to hide content from sighted users. Does not remove content from the accessibility tree. The element is still accessible to screen readers and keyboard focus.

  • The content property: when used with a pseudo-element selector can be used to inject text-only content into the accessibility tree.

  • The display property: when set to none removes the element from the accessibility tree. It is hidden for sighted and non-sighted visitors.

  • The display property: when set to flex, block, or grid and applied to a <table> element, may force the table to be interpreted as a layout table, rather than a data table.

  • The font-size property: when set to 0 will hide text from sighted visitors, but it will still be accessible to screen readers.

  • The height and/or width properties: when set to a value of 0 is hidden for sighted and non-sighted visitors. When these properties are set to a value > 0, the areas not displayed will only be hidden from sighted visitors -- they will still be accessible to screen readers. The behavior of max-height and max-width are similar.

  • The list-style property: when set to none may change how some screen-reader/browser combinations announce the number of items in a list and which current item a visitor is reading.

  • The position property: should be used with care, as it can affect reading order, which must follow the DOM ordering.

  • The opacity property: when set to 0 can be used to hide content from sighted users. Does not remove content from the accessibility tree. The element is still accessible to screen readers and keyboard focus.

  • The overflow property: when set to hidden can be used to hide content from sighted users. Does not remove content from the accessibility tree. The element is still accessible to screen readers and keyboard focus.

  • The text-transform property: when set to uppercase may cause some assistive technology to read shorter words one letter at a type, as if it were an acronym.

Tawnatawney answered 3/5, 2021 at 20:13 Comment(1)
The content property: when used with a pseudo-element selector can be used to inject text-only content into the accessibility tree. ==> Not always true, be very careful: it's generally read by NVDA, but not Jaws. Better is to avoid it because you can't assume 100% that it will or won't be present in the accessibility tree.Eigenvalue
C
0

To hide something, but not for accesibility, you can use these classes. Use a width and height of 1px for best result.

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  white-space: normal;
}

Example how to use it in your html

<nav>
  <ul
    <li class="active">Home <span class="sr-only">is active item</span></li>
    <li>Products</li>
    <li>Contact</li>
  </ul>
</nav>
Carnauba answered 3/5, 2021 at 14:51 Comment(3)
This doesn't answer the question, the OP wants to know what parts of CSS affect the accessibility tree not how to visually hide something so it is still accessible. Even if they did want that I would recommend a more robust class that uses modern techniques instead of margin="-1px" which causes issues and clip-path as clip is deprecated (although we still need it for legacy browsers). Also what is the .sr-only-focusable:focus part meant to achieve?Beam
The css is cross browser for older and modern browsers on any platform. If this causes issues then all BS 4 websites where this class is used will have issues.Carnauba
and they do have problems! That is the problem, hence the title of that answer I gave was "A better alternative to the bootstrap sr-only class!" 😋 hehe. Also what are the second parts meant to do as I don't get how that would make them focusable only to a screen reader? Have a quick read of the answer I linked to, it explains why I changed the 3 properties. It also works all the way back to IE6 so you won't have an issue with it (unless you like pain and want to build a site that works on IE5 of course 🤣🤣)Beam

© 2022 - 2024 — McMap. All rights reserved.