Single or Double Colons in CSS Pseudo‑Elements (:before vs. ::before)

In CSS, pseudo‑elements like :before and :after (and not to be confused with pseudo‑classes like :has or :hover) are an easy way of adding content and styling to your page without modifying the HTML itself. However, one thing that has come up a few times now is the confusion around whether to use a single colon (:) or a double colon (::), e.g. :before vs. ::before.
Here, I intend to give a quick overview of what a pseudo‑element actually is, the history of these differing notations, and why it's important to use the correct one. Spoiler: double colon is more correct, but it really doesn't make much difference overall.
The History Behind Single and Double Colons
Originally, CSS2 and earlier specifications used a single colon (:) for both pseudo‑classes and pseudo‑elements. This created some ambiguity in the code we wrote, as there was no clear distinction between the two pseudo‑types.
For example:
p:before {
content: 'Note: ';
color: blue;
}
p:hover {
color: red;
}At a glance, the example above can be unclear as to whether :before and :hover are functioning as pseudo‑classes or pseudo‑elements, especially for developers new to CSS. The single‑colon notation made it difficult to distinguish between pseudo‑elements like :before, which inserts content, and pseudo‑classes like :hover, which modifies the visual state of an element.
Explanation of the Ambiguity
If you're a seasoned developer, then this probably doesn't matter, but for developers relatively new to CSS, it becomes a pain point that simply isn't necessary:
Pseudo‑Classes
(e.g.,:hover) apply styles based on an element's state (e.g. when hovered over).Pseudo‑Elements
(e.g.,:before): Insert and style content that is not part of the original document structure.
They are really two quite different concerns within our stylesheets.
The Introduction of Double‑Colon Notation
With the introduction of CSS3, the double‑colon notation (::) was introduced to differentiate pseudo‑elements from pseudo‑classes more clearly:
Pseudo‑classes
use a single colon (:). For example::hover,:focus,:active.Pseudo‑elements
use a double colon (::), like this:::before,::after,::first-letter.
This change was designed to help developers quickly identify whether a style targets an element's state or a specific part of the element.
Using the same code example as above, it now looks like this:
p::before {
content: 'Note: ';
color: blue;
}
p:hover {
color: red;
}The difference is subtle, but by using ::before, it is more readily obvious that this is a pseudo‑element that inserts content, whilst :hover remains a pseudo‑class modifying the element's state.
The Correct Usage in Modern CSS
In modern CSS, the 'correct' way to use pseudo‑elements is to write them with a double colon (::) to differentiate them from pseudo‑classes.
Why Does This Matter?
Using the double‑colon syntax aligns new CSS with modern standards and makes the distinction from pseudo‑classes clearer. For compatibility with CSS2 stylesheets, however, specifications require user agents to keep accepting the single‑colon form for :before, :after, :first-line, and :first-letter. That exception does not extend to every pseudo‑element.
Browser Compatibility for Double‑Colon Notation
By the time of this article, double‑colon notation is supported across the main browsers. The practical compatibility question is whether your project still supports an older browser such as Internet Explorer 8.
Supported Browsers
All major modern browsers support the more modern double‑colon syntax (::before, ::after, etc.), including:
- Chrome (since version 1)
- Firefox (since version 1.5)
- Safari (since version 4)
- Safari on iOS (since version 3)
- Opera (since version 7)
- Edge (all versions)
Legacy Browsers
Internet Explorer 8 supports :before and :after with the single‑colon spelling. Internet Explorer 9 also supports ::before and ::after. If IE8 is in your support range, keep the single‑colon form for those selectors.
Fallback for Compatibility
For the four legacy pseudo‑elements, the single‑colon form remains valid compatibility syntax. If an older browser needs that form, use it on its own, as in this example:
p:before {
content: "Note: ";
color: blue;
}Do not combine p:before and p::before in the same comma‑separated selector list as a fallback. An older browser that rejects the double‑colon selector can discard the whole rule, including the single‑colon selector it understands. Use double‑colon notation for new code when your browser range supports it.
Key Takeaways
- Pseudo‑classes always use a single colon, e.g.,
:hoveror:focus. - Pseudo‑elements also used to use single‑colons, (e.g.,
:before);however, that changed in CSS3. - Use
::beforeand::afterfor new code; use their single‑colon forms when an older browser in the project range requires them. - Single‑colon syntax remains a specified compatibility form for
:before,:after,:first-line, and:first-letter, not for pseudo‑elements generally.
Wrapping Up
The difference between :before and ::before may seem minor, but the notation still helps distinguish a pseudo‑element from a pseudo‑class. Use double‑colon for new code, whilst recognising that the four legacy single‑colon forms remain part of the specified compatibility treatment.