CSS is amazing. They help us create stunning websites without learning complex languages like JavaScript etc. We can now use CSS to disable mouse/touch events, make a checkbox look and act like a light bulb, make a design responsive and use CSS gradients to create wicked one-element illustrations. Another flexible addition to CSS was the content property, which on a basic level, allows you to place text content within a :before or :after pseudo element. But knowing web developers, we wont allow content to simply be used without a bit of wizardry. Here are seven clever uses of css content!

Glyph Fonts

You’ve no doubt been to a site that uses glyph fonts and there’s a good chance you’ve used a glyph font library like Font Awesome. If you take a moment to check out the source of these glyph font libraries, you’ll notice that they use CSS content to designate the given icon. Just set the font-family to the glyph font and then modify the content value.

Here’s a sample CSS snippet from Font Awesome:

/* ... */

.fa-twitter-square:before { content: "\f081"; }
.fa-facebook-square:before { content: "\f082"; }
.fa-camera-retro:before { content: "\f083"; }
.fa-key:before { content: "\f084"; }
.fa-gears:before, .fa-cogs:before { content: "\f085"; }
.fa-comments:before { content: "\f086"; }
.fa-thumbs-o-up:before { content: "\f087"; }

/* ... */

You can even create your own glyphs! It’s quite incredible that a glyph can be changed simply modifying the CSS content value but that’s how glyph fonts work!

CSS Counters

The idea of counters makes most developers giggle but CSS counters aren’t those type of counters. CSS counters allow for incremental content labels with pure CSS; multiple layers of counters can be created and counter format can be customized. The Mozilla Developer Network experimented with CSS counters within the table of contents of wiki articles:

#toc ol { counter-reset: toc; } /* counter reset */
#toc ol li { counter-increment: toc; } /* counter increment */
#toc ol li:before { content: counters(toc, '.'); } /* counter display */

The code above adds a period-delimited list structure before list item contents, which would look like:

1  (text)
1.1  (text)
1.2  (text)
1.2.1  (text)

If you want to move away from traditional numeric counter values, you could use special numeric keywords to define the counter format:

#toc ol li:before { content: counter(toc, upper-latin); } /* counter display */

CSS counters are incredibly useful. A table of content is an ideal usage, as is a slide deck which displays slide numbers.

CSS Triangles

Before the CSS triangle technique became a popular, developers needed to use images to create tooltip pointers. And that was incredibly annoying because we’d need to pair image border and background colors with element border and background colors. And whenever you work wih images, you need to accommodate for image dimensions and another HTTP request. With CSS content as a factor we can now make triangular elements with pure CSS:

div.tooltip:before, div.tooltip:after {
    content: " ";
    height: 0;
    position: absolute;
    width: 0;
    border: 10px solid transparent; /* arrow size */

The content value is only whitespace in this case but it’s instrumental in the creation of a tooltip based on pseudo-elements. Now the entire tooltip, arrow and all, can be created with CSS and customizing the tooltip is easy as its its size and colors are created with CSS and border.

Hover or focus any link on a given page and you’ll see the complete URL within the browser’s status bar. What if you’re printing a document though? You don’t get the advantage of the status bar. Luckily you can use content to display the link URL on the printed page:

a:link:after, a:visited:after { content:" [" attr(href) "] "; }

With this snippet, every link which prints will have its URL printed within braces next to the link. Now users who print a page wont miss a beat if they want to look further into a topic. One caveat is that the exact href value is used, so if your site uses relative links, the printed URL may not be as useful as desired.

Setting a different link style for visited links is important but a slightly faded link color isn’t always valuable or apparent enough. Chris Coyier shared a technique on CSS Tricks for styling visited link with a visible check:

a:visited:before { content:  "\2713 "; }

The visible check is much more useful than just a style a link color update. We use a check mark in this case but any other icon could be used to denote that a link has been clicked. Regardless, a visual cue other than color communicates much better that a URL has been visited.

Inserting Images

Hardcoded text, element attributes, and generated content can be displayed with content, but you can also display images via CSS content:

a:before {
    content: url(image.png);

The syntax for using content for imagery is the same as CSS background shorthand syntax. This is useful when looking to avoid using multiple CSS backgrounds on a given element — you can use :before instead!

Localized Labels

CSS is not flexible in that it can conditionally express values but it can communicate values explicitly given to it. If you want to express text regardless of language, you simply need to ensure the text is provided in a custom element attribute and expressed with the correct pseudo element:

a.localized:after { content: " [" attr(data-lang) "]" }

What’s important to realize with this tip is that anything you add in an element attribute is reachable for usage with CSS content. Since adding localized labels would massively bloat a CSS file, using an element attribute as a pseudo-variable allows for easy localization of pseudo-elements wherever desired.

The content property has been traditionally thought of as static but the examples above prove that the content property can be incredibly dynamic when used cleverly. There are likely many other examples of outstanding uses of content so please share them if you have one!