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.
/* Keywords that cannot be combined with other values */
content: normal;
content: none;
/* <string> value, non-latin characters must be encoded */
/* e.g. \00A0 for */
content: "prefix";
/* <url> value */
content: url("http://www.example.com/test.png");
/* <counter> values */
content: counter(chapter_counter);
content: counters(section_counter, ".");
/* attr() value linked to the HTML attribute value */
content: attr(value string);
/* Language- and position-dependent keywords */
content: open-quote;
content: close-quote;
content: no-open-quote;
content: no-close-quote;
/* Except for normal and none, several values */
/* can be used simultaneously */
content: open-quote chapter_counter;
/* Global values */
content: inherit;
content: initial;
content: unset;
| Initial value | normal |
|---|---|
| Applies to | ::before and ::after pseudo-elements |
| Inherited | no |
| Media | all |
| Computed value | On elements, always computes to normal. On ::before and ::after, if normal is specified, computes to none. Otherwise, for URI values, the absolute URI; for attr() values, the resulting string; for other keywords, as specified. |
| Animation type | discrete |
| Canonical order | the unique non-ambiguous order defined by the formal grammar |
Syntax
Values
none- The pseudo-element is not generated.
normal- Computes to
nonefor the::beforeand::afterpseudo-elements. <string>- One or more text characters.
<url>- A URL that designates an external resource (such as an image). If the resource can't be displayed, it is either ignored or a placeholder is shown.
<counter>- The value of a CSS counter, generally a number. It can be displayed using either the
counter()orcounters()function. -
The
counter()function has two forms: 'counter(name)' or 'counter(name, style)'. The generated text is the value of the innermost counter of the given name in scope at the given pseudo-element. It is formatted in the specified style (decimalby default).The
counters()function also has two forms: 'counters(name, string)' or 'counters(name, string, style)'. The generated text is the value of all counters with the given name in scope at the given pseudo-element, from outermost to innermost, separated by the specified string. The counters are rendered in the indicated style (decimalby default). attr(x)- The value of the element's attribute
xas a string. If there is no attributex, an empty string is returned. The case-sensitivity of attribute names depends on the document language. open-quote|close-quote- These values are replaced by the appropriate string from the
quotesproperty. no-open-quote|no-close-quote- Introduces no content, but increments (decrements) the level of nesting for quotes.
Formal syntax
normal | none | [ <content-replacement> | <content-list> ] [/ <string> ]?where
<content-replacement> = <image>
<content-list> = [ <string> | contents | <image> | <quote> | <target> | <leader()> ]+where
<image> = <url> | <image()> | <image-set()> | <element()> | <cross-fade()> | <gradient>
<quote> = open-quote | close-quote | no-open-quote | no-close-quote
<target> = <target-counter()> | <target-counters()> | <target-text()>
<leader()> = leader( <leader-type> )where
<image()> = image( [ [ <image> | <string> ]? , <color>? ]! )
<image-set()> = image-set( <image-set-option># )
<element()> = element( <id-selector> )
<cross-fade()> = cross-fade( <cf-mixing-image> , <cf-final-image>? )
<gradient> = <linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()>
<target-counter()> = target-counter( [ <string> | <url> ] , <custom-ident> , <counter-style>? )
<target-counters()> = target-counters( [ <string> | <url> ] , <custom-ident> , <string> , <counter-style>? )
<target-text()> = target-text( [ <string> | <url> ] , [ content | before | after | first-letter ]? )
<leader-type> = dotted | solid | space | <string>where
<color> = <rgb()> | <rgba()> | <hsl()> | <hsla()> | <hex-color> | <named-color> | currentcolor | <deprecated-system-color>
<image-set-option> = [ <image> | <string> ] <resolution>
<cf-mixing-image> = <percentage>? && <image>
<cf-final-image> = <image> | <color>
<linear-gradient()> = linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )
<repeating-linear-gradient()> = repeating-linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )
<radial-gradient()> = radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )
<repeating-radial-gradient()> = repeating-radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )
<counter-style> = <counter-style-name> | symbols()where
<rgb()> = rgb( [ [ <percentage>{3} | <number>{3} ] [ / <alpha-value> ]? ] | [ [ <percentage>#{3} | <number>#{3} ] , <alpha-value>? ] )
<rgba()> = rgba( [ [ <percentage>{3} | <number>{3} ] [ / <alpha-value> ]? ] | [ [ <percentage>#{3} | <number>#{3} ] , <alpha-value>? ] )
<hsl()> = hsl( [ <hue> <percentage> <percentage> [ / <alpha-value> ]? ] | [ <hue>, <percentage>, <percentage>, <alpha-value>? ] )
<hsla()> = hsla( [ <hue> <percentage> <percentage> [ / <alpha-value> ]? ] | [ <hue>, <percentage>, <percentage>, <alpha-value>? ] )
<side-or-corner> = [ left | right ] || [ top | bottom ]
<color-stop-list> = <color-stop>#{2,}
<ending-shape> = circle | ellipse
<size> = closest-side | farthest-side | closest-corner | farthest-corner | <length> | <length-percentage>{2}
<position> = [[ left | center | right | top | bottom | <length-percentage> ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | [ center | [ left | right ] <length-percentage>? ] && [ center | [ top | bottom ] <length-percentage>? ]]
<counter-style-name> = <custom-ident>where
<alpha-value> = <number> | <percentage>
<hue> = <number> | <angle>
<color-stop> = <color> <length-percentage>?
<length-percentage> = <length> | <percentage>
Examples
Headings and quotes
This example inserts quotation marks around quotes, and adds the word "Chapter" before headings.
HTML
<h1>5</h1>
<p>According to Sir Tim Berners-Lee,
<q cite="http://www.w3.org/People/Berners-Lee/FAQ.html#Internet">I was
lucky enough to invent the Web at the time when the Internet
already existed - and had for a decade and a half.</q>
We must understand that there is nothing fundamentally wrong
with building on the contributions of others.
</p>
<h1>6</h1>
<p>According to the Mozilla Manifesto,
<q cite="http://www.mozilla.org/en-US/about/manifesto/">Individuals
must have the ability to shape the Internet and
their own experiences on the Internet.</q>
Therefore, we can infer that contributing to the open web
can protect our own individual experiences on it.
</p>
CSS
q {
color: blue;
}
q::before {
content: open-quote;
}
q::after {
content: close-quote;
}
h1::before {
content: "Chapter "; /* The trailing space creates separation
between the added content and the
rest of the content */
}
Result
Image combined with text
This example inserts an image before the link. If the image is not found, it inserts text instead.
HTML
<a href="http://www.mozilla.org/en-US/">Mozilla Home Page</a>
CSS
a::before {
content: url("https://mozorg.cdn.mozilla.net/media/img/favicon.ico") " MOZILLA: ";
font: x-small Arial, sans-serif;
color: gray;
}
Result
Targeting classes
This example inserts additional text after special items in a list.
HTML
<h2>Paperback Best Sellers</h2> <ol> <li>Political Thriller</li> <li class="new-entry">Halloween Stories</li> <li>My Biography</li> <li class="new-entry">Vampire Romance</li> </ol>
CSS
.new-entry::after {
content: " New!"; /* The leading space creates separation
between the added content and the
rest of the content */
color: red;
}
Result
Images and element attributes
This example inserts an image before each link, and adds its id attribute after.
HTML
<ul>
<li><a id="moz" href="http://www.mozilla.org/">
Mozilla Home Page</a></li>
<li><a id="mdn" href="https://developer.mozilla.org/">
Mozilla Developer Network</a></li>
</ul>
CSS
a {
text-decoration: none;
border-bottom: 3px dotted navy;
}
a::after {
content: " (" attr(id) ")";
}
#moz::before {
content: url("https://mozorg.cdn.mozilla.net/media/img/favicon.ico") ;
}
#mdn::before {
content: url("https://mdn.mozillademos.org/files/7691/mdn-favicon16.png") ;
}
li {
margin: 1em;
}
Result
Specifications
| Specification | Status | Comment |
|---|---|---|
| CSS Generated Content Module Level 3 The definition of 'content' in that specification. |
Working Draft | |
| CSS Level 2 (Revision 1) The definition of 'content' in that specification. |
Recommendation | Initial definition |
Browser compatibility
| Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
|---|---|---|---|---|---|---|
| Basic support | 1.0 | (Yes) | 1.0 (1.7 or earlier) | 8.0 | 4.0 | 1.0 |
url() support |
1.0 | ? | 1.0 (1.7 or earlier) | 8.0 | 7.0 | 1.0 |
| Feature | Android | Edge | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | 1.0 | (Yes) | 1.0 (1.0) | 8.0 | 9.5 | 1.0 |
url() support |
? | ? | ? | ? | ? | ? |
Quantum CSS notes
- Gecko has a bug whereby the
::beforeand::afterpseudo-elements are still generated even if thecontentproperty value is set tonormalornone. As per spec, they shouldn't be (bug 1387931). This has been fixed in Firefox's new parallel CSS engine (also known as Quantum CSS or Stylo, planned for release in Firefox 57).