W3docs

CSS content Property

The content property is used with:: before and:: after pseudo-elements to generate content inside an element. Try Content Property examples.

The content property is used with the ::before and ::after pseudo-elements to generate content inside an element. Without an explicit value, those pseudo-elements are not rendered at all, so content is what makes a generated box appear in the first place.

This page covers when and how to use content: inserting plain text, pulling in attribute values with attr(), numbering elements with CSS counters, embedding images and quotes, and the gotchas that trip people up (such as generated text being inaccessible to screen readers).

The property accepts the following values:

  • normal
  • none
  • counter
  • attr
  • string
  • open-quote
  • close-quote
  • no-open-quote
  • no-close-quote
  • url
Info

Text inserted with content is not part of the DOM — you cannot select it the way you select normal text, and assistive technology support is inconsistent. Use it for decorative or supplementary content, not for content that must always be available to every reader. The quotes property must be set on the element for open-quote and close-quote to render actual quotation marks.

Initial Valuenormal
Applies to::before and ::after pseudo-elements.
InheritedNo.
AnimatableNo.
VersionCSS2
DOM Syntaxelement.style.content = "none";

Syntax

Syntax of CSS content Property

content: normal | none | counter | attr | string | open-quote | close-quote | no-open-quote | no-close-quote | url | initial | inherit;

Example of the content property:

Example of CSS content Property with normal value

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      p::before {
        content: "Name -";
      }
      .country::before {
        content: normal;
      }
    </style>
  </head>
  <body>
    <h2>Content property example</h2>
    <p>My name is John</p>
    <p class="country">I live in Canada</p>
  </body>
</html>

Result

CSS content Property

Example of the content property with the "string" value:

Example of CSS content Property with string value

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      li:before {
        content: "List item";
      }
      p:after {
        content: " with string value.";
      }
    </style>
  </head>
  <body>
    <h2>Content property example</h2>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
    <p>Here is some paragraph</p>
  </body>
</html>

In the following example, you can see that open-quote cannot appear without close-quote.

Example of the content property with the "open-quote" value:

Example of the content property with open-quote and close-quote values

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      p {
        quotes: open-quote close-quote;
      }
      p::before {
        content: open-quote;
      }
      p::after {
        content: close-quote;
      }
    </style>
  </head>
  <body>
    <h2>Content property example</h2>
    <p>Hello, my name is John</p>
    <p>I am from Canada</p>
  </body>
</html>

Example of the content property with the "open-quote" and "no-close-quote" values:

Example of the content property with "open-quote" and "no-close-quote" values:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      p::before {
        content: open-quote;
      }
      p::after {
        content: no-close-quote;
      }
    </style>
  </head>
  <body>
    <p>Example with content property</p>
  </body>
</html>

Using the attr() value to read an attribute

attr() pulls the value of an HTML attribute into the generated content. A common use is showing the target of a link, or surfacing a data-* attribute as a tooltip-like label. The attribute value is always treated as a string.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      a::after {
        content: " (" attr(href) ")";
        color: #888;
      }
    </style>
  </head>
  <body>
    <p>Visit <a href="https://www.w3docs.com">W3docs</a> to learn more.</p>
  </body>
</html>

This renders the link as Visit W3docs (https://www.w3docs.com) to learn more. — note how a string and attr() are concatenated simply by writing them next to each other.

Using counters to number elements

CSS counters let you generate sequential numbers without touching the HTML. You initialise a counter with counter-reset, advance it with counter-increment, and print it with the counter() function inside content. This is the idiomatic way to number headings, steps, or figures.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body {
        counter-reset: section;
      }
      h2::before {
        counter-increment: section;
        content: "Section " counter(section) ": ";
      }
    </style>
  </head>
  <body>
    <h2>Introduction</h2>
    <h2>Installation</h2>
    <h2>Usage</h2>
  </body>
</html>

Each <h2> is prefixed with Section 1: , Section 2: , and Section 3: automatically.

Inserting an image with the url() value

The url() value embeds an external resource — typically a small icon — into the generated box. This works well for decorative markers, but because the image is not in the DOM it carries no alternative text, so avoid it for meaningful images.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .external::after {
        content: url("https://www.w3docs.com/build/img/favicon.ico");
        margin-left: 5px;
      }
    </style>
  </head>
  <body>
    <p class="external">A link to an external resource</p>
  </body>
</html>
Warning

Generated content is decorative by default. Screen readers may skip it or read it inconsistently across browsers, and users cannot copy it. Never put text that the reader must not miss (such as a price or an error message) only inside a content value.

Values

ValueDescription
normalSets the content to normal. This is the default value.
noneSets the content to nothing. The pseudo-element is not generated.
counterSets the content to a counter value.
attrSets the content to the value of an attribute on the selected element.
stringSets the content to a string of text.
open-quoteSets the content to be an opening quote.
close-quoteSets the content to be a closing quote.
no-open-quoteRemoves the opening quote from the content.
no-close-quoteRemoves the closing quote from the content.
urlSets the content to a URL pointing to a resource, such as an image, sound, or video. If the image cannot be displayed, it will be either ignored or some placeholder will be displayed.
initialSets the property to its default value.
inheritInherits the property from its parent element.

The content property only does something on generated boxes, so it is almost always paired with the pseudo-elements that create them:

  • ::before — inserts generated content before an element's own content.
  • ::after — inserts generated content after an element's own content.

Practice

Practice
Which statements about the CSS content property are correct?
Which statements about the CSS content property are correct?
Was this page helpful?