What Are Good Uses of the CSS 'Content' Property

What are good uses of the css `content` property?

Does css "content" property break the rule of content and separation because css is for presentation not to generation content?

Good point. I'd say it does if it's used for actual data.

The quirksmode page on content shows the limitations pretty well. You can't add any kind of styled content at the moment - it will work with too few browsers. You can add only character data.

The author of the quirksmode airs an interesting opinion:

I feel that we shouldn't use the content declaration at all. It adds content to the page, and CSS is meant for adding presentation to the page, and not content. Therefore I feel that you should use JavaScript if you want to dynamically generate content. CSS is the wrong tool for this job.

I agree with this in general, but sometimes there may be cases where you don't want to rely on JavaScript to do the job. The comma example shown by Martin is a case where I find using content justified (although I personally would be feeling better if the commas would already be served coming from server side - it's what I personally would stick to.)

Also, keep in mind that adding commas and quotes through the content property may look bad when your content is viewed from elsewhere - for example in a search results page.

I'd say use it only sparingly, if you really need it.

Various possible uses of the content: property in css2/css3

Oh, too many to list. Some of the most common cases are:

  • Special numbering, with the counter() function, along with the counter-reset and counter-increment properties

  • Pure CSS clearfix with:

    .foo:after {
    content: "";
    display: block;
    clear: both;
    }
  • Display attributes, eg to print URLs for hyperlinks in a print stylesheet

    a[href]:after {
    content: ' (' attr(href) ') ';
    }
  • Add typographic ornaments that shouldn't be in the HTML because they're presentational. For example, in my blog, I've used it for the ornaments between posts or sidebar links.

  • Add icons to hyperlinks, depending on where they point, like

    a[href^="http://twitter.com/"]:before {
    content: url('twitter-icon.png');
    }
  • Adding a pointer to make a CSS-only speech bubble:

    .bubble {
    position: relative;
    background: silver;
    }

    .bubble:after {
    content: "";
    border:10px solid transparent;
    border-top-color:silver;
    position: absolute;
    bottom:-20px
    }

And many, many other.

Just beware: If something is not presentational, it should probably be in your HTML. Users will not be able to select CSS generated content, and screen readers will ignore it.

content property in CSS

Using content property embeds a virtual content inside an element, it is used with a pseudo :before or :after, so if you use :before, the content will be embedded before.

From MDN :

The content CSS property is used with the ::before and ::after
pseudo-elements to generate content in an element. Objects inserted
using the content property are anonymous replaced elements.

Content property can hold any character, number, entities. For more information, you can refer an article here.

Also, you can get an handy converter here.


This method is also used by font-awesome - Example and other related svg font embedding libraries, where you can simply call classes to the elements and the fonts will be embedded virtually.


Also, just a side information, content generated using CSS content property is inline by default, also this is rendered inside the element and not outside..

Why do the :before and :after pseudo-elements require a 'content' property?

The reason you need a content: '' declaration for each ::before and/or ::after pseudo-element is because the initial value of content is normal, which computes to none on the ::before and ::after pseudo-elements. See the spec.

The reason the initial value of content isn't an empty string but a value that computes to none for the ::before and ::after pseudo-elements, is twofold:

  1. Having empty inline content at the start and end of every element is rather silly. Remember that the original purpose of the ::before and ::after pseudo-elements is to insert generated content before and after the main content of an originating element. When there's no content to insert, creating an additional box just to insert nothing is pointless. So the none value is there to tell the browser not to bother with creating an additional box.

    The practice of using empty ::before and ::after pseudo-elements to create additional boxes for the sole purpose of layout aesthetics is relatively new, and some purists might even go so far as to call it a hack for this reason.

  2. Having empty inline content at the start and end of every element means that every (non-replaced) element — including html and body — would by default generate not one box, but up to three boxes (and more in the case of elements that already generate more than just the principal box, like elements with list styles). How many of the two extra boxes per element will you actually use? That's potentially tripling the cost of layout for very little gain.

    Realistically, even in this decade, less than 10% of the elements on a page will ever need ::before and ::after pseudo-elements for layout.

And so these pseudo-elements are made opt-in — because making them opt-out is not only a waste of system resources, but just plain illogical given their original purpose. The performance reason is also why I do not recommend generating pseudo-elements for every element using ::before, ::after.

But then you might ask: why not have the display property default to none on ::before, ::after? Simple: because the initial value of display is not none; it is inline. Having inline compute to none on ::before, ::after is not an option because then you could never display them inline. Having the initial value of display be none on ::before, ::after is not an option because a property can only have one initial value. (This is why the initial value of content is always normal and it is simply defined to compute to none on ::before, ::after.)

Why do I need an empty `content` property on an ::after pseudo-element?

You cannot style generated content without defining what that content should be. If you don’t really need any content, just an extra “invisible element” to style, you can set it to the empty string (content: '') and just style that.

It’s easy to confirm this yourself: http://jsfiddle.net/mathias/YRm5V/

By the way, the snippet you posted is the micro clearfix hack, which is explained here: http://nicolasgallagher.com/micro-clearfix-hack/

As for your second question, you’ll need an HTML5 shiv (small piece of JavaScript) to make <nav> stylable in some older browsers.

CSS content property: is it possible to insert HTML instead of Text?

Unfortunately, this is not possible. Per the spec:

Generated content does not alter the document tree. In particular, it is not fed back to the document language processor (e.g., for reparsing).

In other words, for string values this means the value is always treated literally. It is never interpreted as markup, regardless of the document language in use.

As an example, using the given CSS with the following HTML:

<h1 class="header">Title</h1>

... will result in the following output:

<a href="#top">Back</a>Title



Related Topics



Leave a reply



Submit