CSS Tutorial menu

CSS Pseudo-elements

A pseudo-element lets you style a part of an element, or add a small piece of decoration, without writing extra HTML.

Pseudo-class or Pseudo-element?

  • A pseudo-class (one colon, :hover) selects a whole element in a certain state.
  • A pseudo-element (two colons, ::before) selects or creates a part of an element.
Pseudo-elementStyles
::beforeA new piece of content at the start of the element
::afterA new piece of content at the end of the element
::first-letterThe first letter of a block of text
::first-lineThe first line of a block of text
::placeholderThe placeholder text of an input
::selectionText the user has highlighted with the mouse
::markerThe bullet or number of a list item

Old CSS used one colon for these, like :before. Browsers still accept it, but two colons is the modern, correct way.

::before and ::after

These two create a small extra box inside the element: ::before goes before the content and ::after goes after it. They need the content property, even if it is empty (content: ""), or nothing shows.

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.price::before {
  content: "Rs ";
  color: #888888;
}
.new::after {
  content: "NEW";
  background-color: crimson;
  color: white;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 8px;
}
.done::before {
  content: "✓ ";
  color: seagreen;
  font-weight: bold;
}
</style>
</head>
<body>

<p class="price new">4,500</p>
<p class="done">HTML course finished</p>
<p class="done">CSS course finished</p>

</body>
</html>
Try it Yourself »

The text "Rs", the badge and the tick marks all come from CSS. The HTML stays clean.

Decorations with an Empty content

With content: "" and position: absolute, a pseudo-element becomes a free shape. Here it draws a coloured line under a heading:

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
h2 {
  position: relative;
  padding-bottom: 10px;
}
h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 60px;
  height: 4px;
  background-color: #264de4;
  border-radius: 2px;
}
</style>
</head>
<body>

<h2>Our Courses</h2>
<p>Web development, graphic design and freelancing.</p>

</body>
</html>
Try it Yourself »

::first-letter and ::first-line

These are useful for articles and stories.

Example

css
.story::first-letter {
  font-size: 3em;
  float: left;
  line-height: 1;
  margin-right: 6px;
  color: #264de4;
}
.story::first-line {
  font-weight: bold;
}

The first letter becomes a big "drop cap", like in a newspaper.

::placeholder, ::selection and ::marker

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
input { padding: 8px; }
input::placeholder {
  color: #9ca3af;
  font-style: italic;
}
::selection {
  background-color: gold;
  color: black;
}
li::marker {
  color: crimson;
  font-weight: bold;
}
</style>
</head>
<body>

<input type="text" placeholder="Search for a course">
<p>Select this sentence with your mouse to see the gold highlight.</p>
<ol>
  <li>Register online</li>
  <li>Visit the institute</li>
  <li>Start your first class</li>
</ol>

</body>
</html>
Try it Yourself »

Things to Remember

  • ::before and ::after do not work on elements that cannot hold content, such as <img> and <input>
  • Text added with content cannot be selected or copied, and some screen readers skip it, so never put important information there
  • Only a few properties work inside ::first-line, ::selection and ::marker (mostly colour and font)

To check a pseudo-element, open your browser's developer tools (F12). You will see ::before and ::after listed inside the element.

Exercise

Exercise

You wrote .tag::after { background: red; width: 10px; height: 10px; } but nothing appears. What is missing?

Learn CSS with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp