Sam Croft

A designer/developer on HTML, CSS, JavaScript and PhoneGap

Using the CSS content property responsibly without compromising your design and markup


Filed in: css, html, usability

CSS has a wonderful property; content. This property allows extra content to be added to a design directly from your stylesheet. Unlike JavaScript, however, it does not add the extra content to your markup after the DOM has loaded. The content will not appear anywhere in your markup, it only appears in the actual rendering of a page.

The content property can be used to great effect providing it is used responsibly in ways that do not break your page if the content, you are adding via this property, did not exist.

How to use the CSS content property

The content property can only be used in conjunction with the CSS pseudo selectors :before and :after allowing you to add content, in this case a string, before and after a given element. Just like this:

h1:before {
	content: "New!";
	color: #F00;
	margin-right: 10px;

Here I am considering a list of article links, each within an h1 element. Using the :before pseudo selector I am adding some text, ‘New!’, before the article heading using the content property. The real-world use of this particular example would be to prefix the latest article titles with the text, ‘New!’. Obviously there would need to be some additional server side code written to determine which articles were ‘new’, assigning those a class name perhaps and then using the :before pseudo selector to just those titles. But that’s not really what this post is about.

Why not just add the text to the title?

Of course, one could easily just append ‘New!’ to the title itself, or prefix the heading with an inline element such as span that contains ‘New!’. But this creates unnecessary markup that isn’t required. There is no need to actually add ‘New!’ in the markup itself because with or without it, the content makes sense. It isn’t part of a sentence, it doesn’t break the content if it’s missing, nor is it required for SEO or accessibility reasons. It is purely an extra visual cue that an article is ‘new’. If we consider the context of this being a blog, the normal data information would indicate how recent an article was. So in this sense, the additional visual cue is just an extra.

Knowing when and when not to use the CSS content property

For me there are certainly situations when the content property is ideal and definitely when using it would just be plain wrong. I stick to these general guidelines when I consider if I should or shouldn’t use the content property.

Do not use the content property if the content you are adding is required to make sense of whatever your page is displaying.

Do use the content property if the content you are adding is just an additional visual cue.

Do use the content property if you would ordinarily use a background-image, or an image itself, to achieve the same effect.

An easy way to check whether you should or shouldn’t be using the content property is to disable your CSS files temporarily and read the content. Does it still make sense? This is an important check when considering SEO and accessibility.

Some real-world examples of using the CSS content property and why its use makes sense

During the development of RITH’s library based game, Lemontree, I used the content property in several prominent places.

Displaying points scores

One of the primary functions of Lemontree is to show people how many points they have scored in total or per action. An action may be something like; “Sam Croft borrowed The Adventures of Huckleberry Finn and scored 10 points” using the following markup:

	<h1>Sam Croft borrowed The Adventures of Huckleberry Finn</h1>
	<h2>10 points</h2>

The way this is actually rendered on Lemontree is so that it appears like this:

Sam Croft borrowed The Adventures of Huckleberry Finn
+10 points

During development we started out actually having the plus symbol appear within the markup itself, but it was always glaringly obvious that this wasn’t really necessary or correct. This was an ideal situation to use the content property, prefixing each score with the plus symbol. With or without the plus symbol the statement makes complete sense, the plus symbol just adds further weight to the statement that they have been awarded points.

The CSS rule:

h2:before {
	content: "+";
	margin-right: 5px;

Displaying player names and their school/department titles

Lemontree players are not only playing for themselves, they are playing to represent their schools and department, contributing to a school/department leader boards. When viewing an individual player feed the main heading for that page is the players name and their school, using the following markup:

	<h1>Sam Croft</h1>
	<h2>Art, Design and Architecture</h2>

But for the heading appears like this:

Sam CroftArt, Design and Architecture

The em dash is added using the content property. Adding it to the markup itself would be incorrect. Why? Because if it was added directly, where should it be added?

Before the closing of the h1?

<h1>Sam Croft—</h1>
<h2>Design and Architecture</h2>

Pass me the sick bucket.

After the opening of the h2?

<h1>Sam Croft</h1>
<h2>—Design and Architecture</h2>

I’m going to be sick in a minute.

Maybe within a span in between?

<h1>Sam Croft</h1>
<h2>Design and Architecture</h2>

I’ve been sick.

Using the content property:

h2 {
	margin-right: 20px;
h2:before {
	margin-left: -20px;
	content: "—";

That feels better.

What is important here, other than the content property is the use of the margin property. Because the two heading elements will be appearing on the same line, by floating left or displaying inline, I am considering a scenario whereby the user is viewing Lemontree on a browser that does not support the content property. Without the right margin on line 2 the two headings would be bunched right up together. This ensures that there is some space between them for older browsers. For browsers that do support the content property I compensate for the aforementioned right margin by applying a negative left margin to the rule applied with the :before pseudo selector.

About the author

I'm Sam Croft - a thirtysomething designer/developer and co-founder of Running in the Halls Ltd—a web and app development studio in Huddersfield, UK. I was educated in graphic design and now specialise in front-end web and app development; my main passion being usability and accessibility. I strongly believe web apps (vs native) are the future and love developing for mobile using the wonderful PhoneGap.

I am a massive sports fan - Formula One in particular. I live in the Pennines with my beautiful wife, Alex. Occasionally I own a large scruffy beard.

I tweet about all of my interests - you should follow me. I also have a .