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

Image by Possessed Photography.

In CSS, pseudoelements like :before and :after (and not to be confused with pseudoclasses 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 pseudoelement 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 pseudoclasses and pseudoelements. This created some ambiguity in the code we wrote, as there was no clear distinction between the two pseudotypes.

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 pseudoclasses or pseudoelements, especially for developers new to CSS. The singlecolon notation made it difficult to distinguish between pseudoelements like :before, which inserts content, and pseudoclasses 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:

  • PseudoClasses

    (e.g., :hover) apply styles based on an element's state (e.g. when hovered over).
  • PseudoElements

    (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 doublecolon notation (::) was introduced to differentiate pseudoelements from pseudoclasses more clearly:

  • Pseudoclasses

    use a single colon (:). For example: :hover, :focus, :active.
  • Pseudoelements

    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 pseudoelement that inserts content, whilst :hover remains a pseudoclass modifying the element's state.


The Correct Usage in Modern CSS

In modern CSS, the 'correct' way to use pseudoelements is to write them with a double colon (::) to differentiate them from pseudoclasses.

Why Does This Matter?

Using the doublecolon syntax aligns new CSS with modern standards and makes the distinction from pseudoclasses clearer. For compatibility with CSS2 stylesheets, however, specifications require user agents to keep accepting the singlecolon form for :before, :after, :first-line, and :first-letter. That exception does not extend to every pseudoelement.


Browser Compatibility for Double‑Colon Notation

Although most modern browsers fully support the doublecolon notation for pseudoelements, you probably should be aware of the pitfalls here in using just the :: notation. Because it generally takes decades for browsers to fully catchup with these types of changes, there are some limitations you should be aware of especially when it comes to compatibility with legacy systems.

Supported Browsers

All major modern browsers support the more modern doublecolon syntax (::before, ::after, etc.), including:

  • Chrome

    (since version 1)
  • Firefox

    (since version 3.5)
  • Safari

    (since version 1.3)
  • Safari on iOS

    (since version 3.2)
  • Opera

    (since version 9.5)
  • Edge

    (all versions)

Legacy Browsers

The potential issue you may face whilst using :: notation is Internet Explorer, where pseudoelements like :before and :after are supported starting from Internet Explorer 5.5. However, they are only recognised with the singlecolon notation (:before, :after) up until Internet Explorer 9, when the browser shifted to doublecolon (::before, ::after).

Fallback for Compatibility

For those four legacy pseudoelements, there is no need to duplicate a selector merely to cover both spellings. The singlecolon form remains the required compatibility syntax, whilst doublecolon is preferred for new authoring. Other pseudoelements should use the syntax defined for them.

p:before,p::before {  content: "Note: ";  color: blue;}

If support for an old browser that does not understand ::before is required, use :before for that selector rather than listing both forms. In a selector list, an unsupported selector can invalidate the whole rule in those older browsers.


Key Takeaways

  • Pseudoclasses always use a single colon, e.g., :hover or :focus.
  • Pseudoelements also used to use singlecolons, (e.g., :before); however, that changed in CSS3.
  • Use ::before and ::after for new code; use their singlecolon forms when an older browser in the project range requires them.
  • Singlecolon syntax remains a specified compatibility form for :before, :after, :first-line, and :first-letter, not for pseudoelements generally.

Wrapping Up

The difference between :before and ::before may seem minor, but the notation still helps distinguish a pseudoelement from a pseudoclass. Use doublecolon for new code, whilst recognising that the four legacy singlecolon forms remain part of the specified compatibility treatment.


Want to find out more?

If you need senior handson support with a complex React or Next.js platform, migration, performance issue, or technical SEO problem, send me the context and I'll tell you where I can help.