Is there a recommended ARIA pattern for making sure that <mark> is properly announced in screen readers?
— Šime Vidas (@simevidas) December 3, 2017
Short answer is no, but there are ways…
The HTML5 mark
element provides a semantic way to highlight portions of text, much as you would using a highlighter on paper.
How does the semantic meaning of the mark
element translate to informing users who cannot see the highlight? Currently it does not, as the accessibility layer implementation across browsers is incomplete, and in browsers where it is supported the assistive technology support is not present.
CSS to fill the gap
One possible method that could be used to provide an indication of the presence of marked text is to use the CSS :before
and :after
pseudo elements. Text indicating the start and end of the marked text is added and then hidden off screen (but still announced by screen readers).
Code example
HTML
<p>
<mark>This text</mark>
is marked as highlighted.
</p>
CSS
mark::before, mark::after {
content:" [highlight start] ";
clip-path: inset(100%);
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
width: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
}
mark::after {
content:" [highlight end] ";
}
See the Pen Using CSS to provide missing semantics for the mark element by steve faulkner (@stevef) on CodePen.
Advantages and disadvantages
-
- It’s simple to implement
- It works well with modern screen readers and evergreen browsers
- it could also be used for other text level elements whose semantics are not exposed aurally, but it would be useful to do so;
ins
anddel
for example. - This method does not work in IE11
- It blurs the line between CSS for presentation and HTML for content
- It could be overused and become an irritant rather than informative
Addendum
You can also make <mark> work better in Windows High Contrast Mode by leaning on system colors: https://t.co/uCBJ071ayp
— Adrian Roselli (@aardrian) December 5, 2017
Comments
Why doesn’t this work in IE11?
If it’s because of the double-colon then I’m fine with the single-colon I’ve been using all along.
If for other reasons, then I’m not certain why we’d bother with the comma-less clip version for IEs 6 and 7.
Thanks for the great tip! But… is the clip() syntax for IE6/7 really needed for pseudo-elements with double colon that are supported only since IE9?
probably not 😉
Because before/after content is not exposed in the DOM or accessibility tree unlike in evergreen browsers
Thanks for the post, this is very close to my own recent experience working with
del
andins
tags. I wanted to point out that in addition to IE, this CSS-based approach also doesn’t work with Firefox and VoiceOver on OS X. In my case, I was generating content using data and handlebars templates, so markup changes were easy to make. I ended up inserting markup before and after the inner content that would be announced but not displayed. The first strategy I used was to add spans that were clipped to zero pixels using CSS. The contents are announced in all environments I tested, but not displayed. The second strategy was to add zero pixel images with either alt attributes or ARIA labels. The combination of zero pixel images and ARIA labels was the only I found that survived being sent as an HTML email and then viewed using Gmail. However, for the vast majority of use cases, I think the CSS :before and :after strategy is better, it has the advantage of evolving whole classes of semantic markup likedel
,ins
, andmark
with a single CSS file.Hi Tony, in regards to Firefox and Voiceover. I don’t think Firefox on Mac robustly supports accessibility, by Mozilla engineers own admission, and I wouldn’t therefore base any coding decisions on Firefox support.