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-element | Styles |
|---|---|
::before | A new piece of content at the start of the element |
::after | A new piece of content at the end of the element |
::first-letter | The first letter of a block of text |
::first-line | The first line of a block of text |
::placeholder | The placeholder text of an input |
::selection | Text the user has highlighted with the mouse |
::marker | The 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
<!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
<!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
.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
<!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
::beforeand::afterdo not work on elements that cannot hold content, such as<img>and<input>- Text added with
contentcannot be selected or copied, and some screen readers skip it, so never put important information there - Only a few properties work inside
::first-line,::selectionand::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?
