F87: CSS Generated Content and WCAG Conformance

The Web Content Accessibility Guidelines (WCAG) does a good job of providing supporting techniques to help reviewers determine if a specific case would violate a given Success Criterion (SC). WCAG 2.0, which became a recommendation at the end of 2008, has carried these techniques over to WCAG 2.1, finalized in June 2018. In that decade, a lot has changed in support for standards among browsers and assistive technology (AT), along with heuristics in AT based on real world code.

WCAG 2 has a Success Criterion (SC) at Level A related to ensuring information is available to AT, either programmatically or as plain text (1.3.1 Info and Relationships). It includes ensuring you do not render data grids as ASCII columns, using tables for layout, or mis-using ARIA’s presentation role.

That WCAG SC also has a technique on CSS generated content, specifically F87: Failure of Success Criterion 1.3.1 due to inserting non-decorative content by using :before and :after pseudo-elements and the ‘content’ property in CSS. Yes, that is its full name (that verbosity is not a bad thing).

I know from experience that some people use the WCAG Failures techniques as a quick way to evaluate whether a page violates a WCAG SC. F87 has a straightforward test procedure:



  1. Examine all content inserted through use of the :before and :after pseudo-elements and the content property

  2. Verify that the content is decorative.

  3. If the inserted content is not decorative, check that the information is provided to assistive technologies and is also available when CSS is turned off.

Expected Results

  • If checks #2 or #3 are false, then this failure condition applies and the content fails this Success Criterion.

Armed with this, some people will wade into the CSS for a page and look for ::before/:before or ::after/:after selectors. If they find non-decorative text in the content property, they flag the entire page for failure.

The reason I am talking about text here is because added text is rarely decorative. Modern browser and screen reader pairings will read it (a far cry from my 2012 post on chromatic fonts that relied on screen readers not reading it). If CSS is turned off, that content will be gone (of course).

To me, failing on this alone is accessibility pedantry. It does not take into account the audience and its technology. It is worrying about standards over users, counter to the W3C Priority of Constituencies which puts users first (a whole three steps ahead of theoretical purity).


It is completely fair to disagree with me. If you do, then I want you to consider if the following are automatic fails.

Link Targets and Destinations

This site uses CSS to identify links that open in a new window. It looks for the target attribute. It also identifies links to PDF files and links to the Wayback Machine with CSS. It does it not by adding icons, but by adding non-decorative text content to a link.

Link targets are not conveyed to users until the link is followed. Files or Wayback destinations are typically conveyed by exploring the link — hovering with a pointer, a long press to trigger a pop-up, or putting focus on the link and looking in the browser status bar. Screen reader users will not hear either of these cases by default. Mobility impaired or voice users might need to take extra steps. But these styles put it into the link itself as plain text.

main a[href$=".pdf"]::after
		{	content: " (PDF)"; }

main a[target^="_"]::after
		{	content: " (opens in new window/tab)"; }

main a[href^="http://web.archive.org/"]::after, a[href^="https://web.archive.org/"]::after
		{	content: " (this a link to an archived version of the page)"; }

If CSS is disabled then the user loses that benefit, but no functionality nor content beyond what the browser already provides for a link.

Should this trigger an automatic 1.3.1 failure under F87?

Each of <ins>, <del>, <mark>, <s>

We know, with the recent exception of <del> in NVDA with Chrome, that <ins>, <del>, <mark>, and <s> are not announced by screen readers. This can make it a challenge for these users to do everything from code reviews to recognize price changes on ecommerce sites.

Steve Faulkner put together a post showing how using CSS generated content can take elements that browsers do not expose to screen readers and let these users know of their presence. I expanded on it in my post Tweaking Text Level Styles.

mark::before	{	content: " [highlight start] "; }

mark::after	{	content: " [highlight end] "; }

del::before	{	content: " [deletion start] "; }

del::after	{	content: " [deletion end] "; }

ins::before	{	content: " [insertion start] "; }

ins::after	{	content: " [insertion end] "; }

s::before	{	content: " [start of stricken text] "; }

s::after	{	content: " [end stricken text] "; }

With this CSS a screen reader user can hear when entering and exiting content that is marked, inserted, deleted, or stricken. If CSS is disabled then the user loses that benefit, but loses no functionality nor content beyond what the browser already provides for these elements.

Should this trigger an automatic 1.3.1 failure under F87?

Emoji Labeling

Léonie Watson wrote how to make emoji more accessible to screen reader users with aria-label, and I expanded on it to support sighted users as well (Accessible Emoji, Tweaked). In this case, I use ::after to visually display the content of the aria-label attribute. Essentially taking an accessibility affordance for screen reader users and expanding it to support sighted users across contexts.

span[role=img][aria-label]:focus::after, span[role=img][aria-label]:hover::after
		{	[…]
			content: attr(aria-label);
			[…] }

With CSS disabled, screen reader users still hear the aria-label, but that extra enhancement for sighted users is lost. The user loses no functionality nor content beyond what the browser already provides.

Should this trigger an automatic 1.3.1 failure under F87?

Print Styles

I am of the opinion that a good set of print styles will incorporate content that is typically restricted to the native web experience. After all, designing for print is responsive design.

My print styles lean on CSS generated content to expand URLs on links and provide other content where needed, such as expanded emoji meanings.

@media print {
		{	content: " (" attr(aria-label) ") "; }

	main a[href]::after
		{	content: " [" attr(href) "] "; }

If CSS is disabled, these will not print with the page content. The user loses no functionality nor content beyond what the browser already provides.

Should this trigger an automatic 1.3.1 failure under F87?


If any of my examples constitutes a failure under F87 and therefore a violation of SC 1.3.1 from the perspective of my client, then I will document my reasoning and include it with my strongly worded letter. I may also look for a client who cares about users over theoretical purity.

Strict adherance to WCAG techniques in light of changing technologies and best practices is a form of Uncanny A11y that I have no interest in perpetuating. F87 taken strictly contributes to that.



This is a great post. Also worth noting that CSS pseudo elements *are* supposed to be included in accessible name computation, as per the spec:


Personally I’ve always been rubbed the wrong way by the idea that your site needs to work without CSS. I get the importance of allowing a user to modify/supplement their own stylesheet, but removing the author’s CSS entirely? That seems like expecting a car to work after you’ve ripped out the steering wheel.

Separation of concerns between HTML and CSS has never worked flawlessly anyway. Consider the example of using a CSS class to set display: none. You’re controlling content via CSS (even though that’s supposed to be the domain of HTML). A user who disables CSS is now going to get a bunch of content that the author never intended them to get. Is that the author’s fault?

In response to James. Reply

Your comment reminds me of Léonie Watson’s post Short note on progressive ARIA where she points out that some properties (and styles, as you cite) should only be added by script after confirming all the assets have loaded. Otherwise, as you also note, it can be a mess.

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.