docs.rodeo

MDN Web Docs mirror

content

{{CSSRef}} 

The content CSS property replaces content with a generated value. It can be used to define what is rendered inside an element or pseudo-element. For elements, the content property specifies whether the element renders normally (normal or none) or is replaced with an image (and associated “alt” text). For pseudo-elements and margin boxes, content defines the content as images, text, both, or none, which determines whether the element renders at all.

Objects inserted using the content property are anonymous {{ glossary("replaced elements")}} .

{{InteractiveExample("CSS Demo: content", "tabbed-shorter")}} 

.topic-games::before {
  content: "🎮 " / "games";
}

.topic-weather::before {
  content: "⛅ " / "cloudy";
}

.topic-hot::before {
  content: url("/shared-assets/images/examples/fire.png") / "On fire";
  margin-right: 6px;
}
<p class="topic-games">Game News: A new inFamous is not planned</p>

<p class="topic-weather">
  Weather for Today: Heat, violent storms and twisters
</p>

<p class="topic-hot">Trending Article: Must-watch videos of the week</p>

Syntax

/* Keywords that cannot be combined with other values */
content: normal;
content: none;

/* <content-replacement>: <image> values */
content: url("http://www.example.com/test.png");
content: linear-gradient(#e66465, #9198e5);
content: image-set("image1x.png" 1x, "image2x.png" 2x);

/* speech output: alternative text after a "/"  */
content: url("../img/test.png") / "This is the alt text";

/* <string> value */
content: "unparsed text";

/* <counter> values, optionally with <list-style-type> */
content: counter(chapter_counter);
content: counter(chapter_counter, upper-roman);
content: counters(section_counter, ".");
content: counters(section_counter, ".", decimal-leading-zero);

/* attr() value linked to the HTML attribute value */
content: attr(href);

/* <quote> values */
content: open-quote;
content: close-quote;
content: no-open-quote;
content: no-close-quote;

/* <content-list>: a list of content values. 
Several values can be used simultaneously */
content: "prefix" url(http://www.example.com/test.png);
content: "prefix" url("/img/test.png") "suffix" / "Alt text";
content: open-quote counter(chapter_counter);

/* Global values */
content: inherit;
content: initial;
content: revert;
content: revert-layer;
content: unset;

Values

The value can be:

The keywords and data types mentioned above are described in more detail below:

Formal definition

{{cssinfo}} 

Formal syntax

{{csssyntax}} 

Accessibility

CSS-generated content is not included in the DOM. Because of this, it will not be represented in the accessibility tree and certain assistive technology/browser combinations will not announce it. If the content conveys information that is critical to understanding the page’s purpose, it is better to include it in the main document.

If inserted content is not decorative, check that the information is provided to assistive technologies and is also available when CSS is turned off.

Examples

The first five examples create generated content on pseudo-elements. The last three are examples of element replacement.

Appending strings based on an element’s class

This example inserts generated text after the text of elements that have a particular class name. The text is colored red.

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 DOM node's content and the generated content
                       being added. */
  color: red;
}

Result

{{EmbedLiveSample('Appending_strings_based_on_an_elements_class', '100%', 160)}} 

Quotes

This example inserts differently colored quotation marks around quotes.

HTML

<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>
<p lang="fr-fr">
  Mais c'est Magritte qui a dit,
  <q lang="fr-fr"> Ceci n'est pas une pipe. </q>.
</p>

CSS

q {
  color: #00f;
}

q::before,
q::after {
  font-size: larger;
  color: #f00;
  background: #ccc;
}

q::before {
  content: open-quote;
}

q::after {
  content: close-quote;
}

Result

{{EmbedLiveSample('Quotes', '100%', 200)}} 

Note the type of quotes generated is based on the language. Browsers add open- and close-quotes before and after {{HTMLElement("q")}}  elements by default, so the quotes in this example would appear without them being explicitly set. They could have been turned off by setting the respective content property values to no-open-quote and no-close-quote, or by setting them both to none. They can also be turned off by setting the {{cssxref("quotes")}}  property to none instead.

Adding text to list item counters

This example combines a counter sandwiched between two <string>s prepended to all list items, creating a more detailed marker for list items ({{HTMLElement("li")}} ) within unordered lists ({{HTMLElement("ol")}} ).

HTML

<ol>
  <li>Dogs</li>
  <li>Cats</li>
  <li>
    Birds
    <ol>
      <li>Owls</li>
      <li>Ducks</li>
      <li>Flightless</li>
    </ol>
  </li>
  <li>Marsupials</li>
</ol>

CSS

ol {
  counter-reset: items;
  margin-left: 2em;
}
li {
  counter-increment: items;
}
li::marker {
  content: "item " counters(items, ".", numeric) ": ";
}

Result

{{EmbedLiveSample('Adding_text_to_list_item_counters', '100%', 200)}} 

The generated content on each list item’s marker adds the text "item " as a prefix, including a space to separate the prefix from the counter, which is followed by ": ", a colon and an additional space. The {{cssxref("counters", "counters()")}}  function defines a numeric items counter, in which the numbers of nested ordered lists have their numbers separated with a period (.) in most browsers.

Strings with attribute values

This example is useful for print stylesheets. It uses an attribute selector to select every fully qualified secure link, adding the value of the href attribute after the link text as the content of the {{cssxref("::after")}}  pseudo-element.

HTML

<ul>
  <li><a href="https://mozilla.com">Mozilla</a></li>
  <li><a href="/">MDN</a></li>
  <li><a href="https://openwebdocs.org">OpenWebDocs</a></li>
</ul>

CSS

a[href^="https://"]::after
{
  content: " (URL: " attr(href) ")";
  color: darkgreen;
}

Result

{{EmbedLiveSample('Strings_with_attribute_values', '100%', 200)}} 

The generated content is the value of the href attribute, prepended by "URL: ", with a space, all in parentheses.

Adding an image with alternative text

This example inserts an image before all links. Two content values are provided. The later content value includes an image with alternative text that a screen reader can output as speech.

HTML

<a href="https://www.mozilla.org/en-US/">Mozilla Home Page</a>

CSS

The CSS to show the image and set the alternative text is shown below. This also sets the font and color for the content.

a::before {
  content: url("https://mozorg.cdn.mozilla.net/media/img/favicon.ico") /
    " MOZILLA: ";
}

Result

{{EmbedLiveSample('Adding_an_image_with_alternative_text', '100%', 60)}} 

[!NOTE] The alternative text value is exposed in the browser’s accessibility tree. Refer to the See also section for browser-specific accessibility panels.

If using a screen reader, it should speak the word “MOZILLA” when it reaches the image. You can select the ::before pseudo-element with your developer tools selection tool, and view the {{glossary("accessible name")}}  in the accessibility panel.

Element replacement with URL

This example replaces a regular element! The element’s contents are replaced with an SVG using the {{cssxref("url_value", "&lt;url&gt;")}}  type.

Pseudo-elements aren’t rendered on replaced elements. As this element is replaced, any matching ::after or ::before are not generated or applied. To demonstrate this, we include an ::after declaration block, attempting to add the id as generated content. This pseudo-element will not be generated as the element is replaced.

HTML

<div id="replaced">This content is replaced!</div>

CSS

#replaced {
  content: url("mdn.svg");
}

/* will not show if element replacement is supported */
div::after {
  content: " (" attr(id) ")";
}

Result

{{EmbedLiveSample('Element_replacement_with_url', '100%',400)}} 

When generating content on regular elements (rather than just on pseudo-elements), the entire element is replaced. This means that ::before and ::after pseudo-elements are not generated.

Element replacement with <gradient>

This example demonstrates how an element’s contents can be replaced by any type of <image>, in this case, a CSS gradient. The element’s contents are replaced with a {{cssxref("gradient/linear-gradient", "linear-gradient()")}} . We provide alt text because all images should be described for accessibility.

HTML

<div id="replaced">I disappear</div>

CSS

div {
  border: 1px solid;
  background-color: #ccc;
  min-height: 100px;
  min-width: 100px;
}

#replaced {
  content: repeating-linear-gradient(blue 0, orange 10%) /
    "Gradients and alt text are supported";
}

Result

{{EmbedLiveSample('Element_replacement_with_gradient', '100%', 200)}} 

Check the browser compatibility chart. All browsers support gradients and all browsers support replacing elements with images, but not all browsers support gradients as a content value.

Element replacement with image-set()

This example replaces an element’s content with a {{cssxref("image/image-set", "image-set()")}} . If the users display has normal resolution the 1x.png will be displayed. Screens with a higher resolution will display the 2x.png image.

HTML

<div id="replaced">I disappear!</div>

CSS

div {
  width: 100px;
  border: 1px solid lightgrey;
}
#replaced {
  content: image-set(
    "1x.png" 1x,
    "2x.png" 2x
  ) / "DPI";
}

Result

{{EmbedLiveSample('Element_replacement_with_image-set', '100%', 110)}} 

Specifications

{{Specifications}} 

Browser compatibility

{{Compat}} 

See also

In this article

View on MDN