CSS Content Pseudo-elements

The ::before and ::after pseudo-elements inject generated content into an element using the content property, useful for icons, labels, and decorative touches.

::before and ::after create a child at the very start or end of an element's content. They only appear when you give them a content property, even if that value is an empty string. This makes them ideal for decoration that does not belong in the HTML.

The required content property

A required-field marker

<!DOCTYPE html>
<html>
<head>
<style>
.required::after {
  content: " *";
  color: #c00;
}
</style>
</head>
<body>

<label class="required">Email address</label>

</body>
</html>

What content can hold

  • A text string, such as content: "Read more"
  • An empty string for a purely decorative box
  • An escaped Unicode character, such as content: "\201C" for a curly quote
  • The value of an attribute, using content: attr(data-label)

Adding decorative quotation marks

A large opening quote

<!DOCTYPE html>
<html>
<head>
<style>
blockquote::before {
  content: "\201C";
  font-size: 3rem;
  color: #ccc;
  vertical-align: -0.4em;
}
</style>
</head>
<body>

<blockquote>Simplicity is the ultimate sophistication.</blockquote>

</body>
</html>

Empty content as a shape

A decorative divider

<!DOCTYPE html>
<html>
<head>
<style>
.divider::after {
  content: "";
  display: block;
  width: 40px;
  height: 3px;
  background: #00643c;
  margin: 12px auto;
}
</style>
</head>
<body>

<h2>Section title</h2>
<div class="divider"></div>
<p>Section content follows the divider.</p>

</body>
</html>
Note: Screen readers may or may not read generated content, so never put essential information, such as a form label or a critical instruction, only inside a content property.