Skip to: content, navigation

by Tommy Olsson and Paul O’Brien

content (CSS property)

Browser support full matrix
IE7 FF1.5+ Saf1.3+ Op9.2+
None Partial Partial Partial
Spec
Inherited Initial Version
No normal CSS2, 2.1

Example

This style rule inserts the text “You are here:” before the element with the ID "breadcrumbs":

#breadcrumbs:before {
  content: "You are here:";
  margin-right: 0.5em;
}

Try it yourself!View all demos

Description

The content property, used in conjunction with the :before or :after pseudo-elements, inserts generated content.

Use the display property to control the type of box that’s generated for the content.

Note that the generated content is only rendered—it doesn’t appear in the DOM tree. In other words, generated content doesn’t alter the document as such—only the presentation.

That said, generated content is still matched by pseudo-elements like :first-letter and :first-line.

Here are some additional examples that demonstrate more advanced usage of generated content, including the use of the counter-increment and counter-reset properties.

This style rule adds the URI, enclosed in angle brackets, after links when the document’s printed to paper:

@media print {
  a[href]:after {
    content: "<" attr(href) ">";
  }
}

These CSS3 style rules format paragraphs within a block quotation in the way that’s common in (American) English novels:

blockquote p {
  margin: 0;
  text-indent: 1em;
  quotes: "\201c" "\201d";
}
blockquote p:first-of-type {
  text-indent: 0;
}
blockquote p::before {
  content: open-quote;
}
blockquote p::after {
  content: no-close-quote;
}
blockquote p:last-of-type::after {
  content: close-quote;
}

These style rules add the word “Chapter” and a chapter number before every h1 heading, and prefix every h2 heading with the chapter number and a section number:

body {
  counter-reset: chapter;
}
h1 {
  counter-increment: chapter;
  counter-reset: section;
}
h2 {
  counter-increment: section;
}
h1:before {
  content: "Chapter " counter(chapter) ": ";
}
h2:before {
  content: counter(chapter) "." counter(section) " ";
}

These style rules apply a hierarchical numbering system to items in ordered lists (for example, 1, 1.1, 1.1.1 … and so on):

ol {
  counter-reset: item;
  margin: 0;
  padding: 0;
}
ol>li {
  counter-increment: item;
  list-style: none inside;
}
ol>li:before {
  content: counters(item, ".") " - ";
}

Value

The value of content is either the keyword none, the keyword normal, the keyword inherit, or one or more content specifications (strings, URIs, counters, or quote characters) separated by whitespace.

Using the value normal, we can reset or clear a previously specified content declaration. From an authoring standpoint, there’s no real difference between the values normal and none, except that there’s currently no browser support for none. According to the CSS2.1 specification, if none is specified, the pseudo-element isn’t generated, and if normal is specified for the :before or :after pseudo-elements, it acts like none. Furthermore, if content is specified for other element types, the computed value should aways be normal. However, these kinds of details are targeted towards browser makers rather than CSS authors, so you shouldn’t worry if they’re confusing.

A string value inserts the specified string. If you want a newline character in the generated content, you can use the \a escape, but the generated content is subject to the white-space property, so you’ll need to modify its value for the newline to be rendered as such.

A URI value inserts content read from the specified external resource. The Changes section in the CSS2.1 specification says that this value type has been dropped, but it’s still listed in the normative section for the content property.

A counter value inserts the current value(s) of the specified counter(s). It can be expressed using two different functional notations, both of which have two forms. The counter(name) notation inserts the current value of the counter with the specified name. The counters(name, separator) notation inserts the values of all counters with the specified name, separated by the specified separator string. Both notations also take an optional list style argument (decimal by default) as the last argument, to control the style of the output—for example, counter(item, upper-roman). The keywords available for the list style argument match those available for the list-style-type property.

See counter-reset and counter-increment for details about counters.

The attr(identifier) notation inserts the value of the attribute whose name is specified by the identifier. Note that the argument is an identifier; it shouldn’t be enclosed in quotes.

The open-quote and close-quote values insert the corresponding quotation mark specified in the quotes property. These values also increment or decrement the nesting level for quotes.

The no-open-quote and no-close-quote values don’t insert any content, but they’ll increment or decrement the nesting level for quotes.

See quotes for details about quotes.

Compatibility

IE5.5None
6.0None
7.0None
Firefox1.0None
1.5Partial
2.0Partial
Safari1.3Partial
2.0Partial
3.0Partial
Opera9.2Partial
9.5Partial

Internet Explorer for Windows versions up to and including 7 don’t support generated content at all.

Firefox versions up to and including 2, and Opera versions up to and including 9.2 don’t support the value none. Safari versions up to and including 3 don’t support the values none or normal. An empty string can be used instead to reset a previous declaration.

In Opera, up to and including version 9.5:

  • Counters used without a counter-reset have global scope instead of the scope of the elements for which they are used.
  • When the quote nesting level isn’t within the number of pairs defined for the quotes property, open-quote inserts the last-defined close quote character, while close-quote inserts the default close quote character.

Opera and Safari 3 (partially) also support content in contexts other than the :before and :after pseudo-elements. In these cases, the content of the element is replaced by the value of the content property.

Related Reading

User-contributed notes

ID:
#7
Date:
Fri, 20 Jun 2008 03:48:14 GMT
Contributed by:
Montgomery
Status:
This note has not yet been confirmed for accuracy and relevance.

When trying to insert generated content that includes Unicode characters, the syntax always seemed confusing.

In other words, these do _not_ produce the desired result:
content: "&mdash;";
content: "&#8212;";
content: "\u2014";

On the other hand, this does work:

blockquote cite:before {
content: "\2014 ";
}

ID:
#6
Date:
Thu, 31 Jan 2008 21:25:17 GMT
Contributed by:
hyperhtml
Status:
This note has not yet been confirmed for accuracy and relevance.

I have the same issue with pactum and valsgalore but in Opera 9.25

ID:
#4
Date:
Thu, 03 Jan 2008 06:13:28 GMT
Contributed by:
pactum
Status:
This note has not yet been confirmed for accuracy and relevance.

Ditto. Same problem in FF for me.

ID:
#3
Date:
Mon, 10 Dec 2007 21:55:37 GMT
Contributed by:
valsgalore

The content of this page is getting covered up by the right sidebar (in FF but not IE 7). I've only been to a few other pages, but this hasn't happened on them.

ID:
#2
Date:
Fri, 07 Dec 2007 03:22:43 GMT
Contributed by:
GuidoSan

At 1024 by 768 in Firefox 2.0.0.11 the right side of the content area of this page is being cut off by the third column.

Add a note

To post a note on this topic, please log in with your SitePoint username and password. If you don't have an account yet, you can create a new account for free.

Related Products

The Principles of Beautiful Web Design

Best Seller!

You don’t need to go to Art School to design great looking web sites!

Book Cover: The Principles of Beautiful Web Design

Download the FREE sample chapters