Skip to main content
Home / CSS Almanac / Properties / C / content

The content property in CSS is used in conjunction with the pseudo-elements ::before and ::after. It is used to literally insert content. There are four value types it can have.

String

.name::before {
  content: "Name: ";
}

Then an element like this:

<div class="name">Chris</div>

Would render like this:

Name: Chris

It could also be an empty string, which is commonly seen in things like the clearfix.

Counter

div::before {
  content: counter(my-counter);
}

More information about that.

Image

div::before {
  content: url(image.jpg);
}

This is literally an image on the page like would be. It could also be a gradient. Note that you cannot change the dimensions of the image when inserted this way. You could also insert an image by using an empty string for the content, making it display: block in some way, sizing it, and using background-image. That way you could re-size it with background-size.

Attribute

You can use values (strings, anyway) that are taken right from attributes in the HTML.

<div data-visual-label="Widget Rating">60</div>
[data-visual-label]::before {
  content: attr(data-visual-label) ": ";
}

/* Classic print trick! Show URLs! */
@media (print) {
  a[href]::after {
    content: " (" attr(href) ") "; /* you could combine a url() in here even if you wanted */
  }
}

The attr() function doesn’t have “types” just yet, so you can’t pass a value like 20px (just strings), but someday!

Alternative Text

The spec says that you can use a / in the syntax to list alternate text. For example…

.el::before {
  content: "⭐️" / "Alternate Text for that star";

  content: "→" / ""; /* Visual only, don't read. */
}

Perhaps you could use it like…

<ul aria-label="To Do List">
  <li>Make Bed</li>
  <li data-alt-pseudo="Completed">Grocery Shop</li>
  <li>Sweep Driveway</li>
</ul>
[data-alt-pseudo="Completed"]::before {
  content: "✅"; /* fallback */
  content: "✅" / attr(data-alt-pseudo);
}

More Information

Content inserted in this way isn’t really in the DOM, so it has some limitations. For instance, you can’t attach an event directly (only) to a pseudo-elements. It is also inconsistent whether or not text inserted in this way is read by screen readers (it usually is these days) or if you can select it (it usually isn’t these days).

Browser Support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
429123.1

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
81682.13.2

For Opera, url() only supported in version 7+.