CSS generated content is not content

CSS is designed primarily to enable the separation of document content (written in HTML or a similar markup language) from document presentation. Prior to CSS, nearly all of the presentational attributes of HTML documents were contained within the HTML markup; all font colors, background styles, element alignments, borders and sizes had to be explicitly described, often repeatedly, within the HTML (Wikipedia) The separation of HTML from CSS makes it easier to maintain sites, share style sheets across pages, and tailor pages to different environments. This is referred to as the separation of structure (or: content) from presentation.(W3C)

Cascading Stylesheets is intended to facilitate the separation of content from presentation. Not to add to, modify, or delete content.

Generated content does not alter the document tree. In particular, it is not fed back to the document language processor (e.g., for reparsing). http://www.w3.org/TR/CSS2/generate.html#propdef-content In other words, “Content specified in a stylesheet does not become part of the DOM.” (MDN)

Good Uses of Generated Content

Among the better uses of generated content is to provide supplementary information or presentation to make the content easier to understand. One way to do this is to add icons that add context to things like links and buttons to inform users about the purpose of the link. Chris Coyier has a few good examples at Common Unicode Icons. What makes Chris’s examples (most of them) good is that he combines these unicode icons with either an obvious format or text, or both. For instance:

  <a href="mailto:chriscoyier@gmail.com">
    chriscoyier@gmail.com
  </a>

and

<p class="important">
  REMEMBER: drink slushies too fast.
</p>

(See the output at http://jsfiddle.net/karlgroves/MQqG9/

Many other examples exist that use actual icons. In the first example above, it is obviously an email address he has front-loaded with an icon. In the latter case, he’s front loaded the text with the word “Remember” implying importance (admittedly, actually using the word Important would be even better). By providing an extra icon, visual users get an increased level of usability because they’re more quickly able to understand the nature of the content.

Bad Uses of Generated Content

The problem with CSS generated content is that it is not content. As I mentioned before, CSS generated content does not become part of the DOM. This means this content is not actually available to users of assistive technologies because the relevant object information isn’t passed through the accessibility APIs. One bad example can be seen over at Signify “PDF Bombs”.


/* Add " (PDF)" text after links that go to PDFs */ 
a[href$=".pdf"]:after { 
    content: " (PDF)"; 
} 

/* If file size specified as data attribute, use that too */ 
a[href$=".pdf"][data-size]:after { 
    content: " (PDF, " attr(data-size) ")"; 
}

See it at: http://jsfiddle.net/karlgroves/83C2c/1/.

On the surface, this seems great. This link has been appended with an indication that the content is a PDF and tells us how big the PDF document is. This is useful information, for sure. Unfortunately this information isn’t available to all users because it isn’t part of the DOM. Here’s another example showing a pattern I see a lot of lately:

<a href="https://twitter.com/karlgroves"></a>
a.twitter:after {
    content:url('path/to/twitter_icon.png');
}

See it at: http://jsfiddle.net/karlgroves/dW4LU/1/

In this case we see a link that has no text at all. Instead generated content places an icon there. Because it is generated content you can’t place an alt attribute on the image. As a result, accessibility APIs cannot calculate an accessible name for the link.

What about Icon Fonts?

Icon fonts, such as Font Awesome, place their icons into the interface exactly as I’ve described: as generated content. So <i class="icon-home"></i> creates a “Home” icon via generated content on that <i> tag. Your nifty toolbar that uses only icon fonts is inaccessible. Like all generated content, it is best used as a visual supplement for existing content, not a replacement. For a good example, check out some of Font Awesome’s Examples for Navigation

Conclusion

If what you’re working with is content, it must be part of the DOM. That means using actual content and not CSS generated content. The inclusion of additional icons and the like can be an improvement, in terms of overall usability, but the additional icons must be in the foreground. For instance, here’s the same PDF link added with jQuery: http://jsfiddle.net/karlgroves/avdce/1/. Another approach would be to add off-screen text, which would function like an alt attribute. Here’s the toolbar, fixed http://codepen.io/karlgroves/pen/Ktdem. This method is less ideal in that it doesn’t help users not on screen readers. Either way, understand that CSS generated content isn’t actually content, because it isn’t actually in the document tree.

If you are interested in learning about the next generation in Web Accessibility Testing, sign up for the release of Tenon.io
If you or your organization need help with accessibility consulting, strategy, or accessible web development, email me directly at karl@karlgroves.com or call me at +1 443-875-7343. Download Resume [MS Word]

One Comment

  • Posted August 27, 2013 at 11:28 am   Permalink

    I used to agree a few years ago, but I am not today.

    First: The attribute is called “content” and it is content that gets inserted before the content of the element that is targeted by CSS. That means it is content that results out of an property of the element.

    Second: If CSS shouldn’t affect the meaning of the HTML, why isn’t a screenreader on top of Firefox reading list elements with list style none and why isn’t content read that has display none applied. (Firefox gives the content of generated content to Accessibility APIs, that makes your point about PDF bombs invalid, also that’s the problem with icon fonts that are mapped to real letters E = Edit symbol as only E is read instead of nothing – and providing an hidden alternative text.)

    That’s why this Bugzilla bug should be closed as soon as possible so we can actually select and search for generated content. It might be overused and often wrongly used, but that only means we have to educate better.

Post a Comment