Note the double-colon
::before versus the single-colon
:before. Which one is correct?
Technically, the correct answer is
::before. But that doesn’t mean you should automatically use it.
The situation is that:
- double-colon selectors are pseudo-elements.
- single-colon selectors are pseudo-selectors.
::before is definitely a pseudo-element, so it should use the double colon.
The distinction between a pseudo-element and pseudo-selector is already confusing. Fortunately,
::before are fairly straightforward. They literally add something new to the page, an element.
But something like
::first-letter is also a pseudo-element. The way I reason that out in my brain is that it’s selecting a part of something in which there is no existing HTML element for. There is no
<span> around that first letter you’re targeting, so that first letter is almost like a new element you’re adding on the page. That differs from pseudo-selectors which are selecting things that already exist, like the
:nth-child(2) or whatever.
::before is a pseudo-element and a double-colon is the correct way to use pseudo-elements, should you?
There is an argument that perhaps you should use
:before, which goes like this:
- Internet Explorer 8 and below only supported :before, not
- All modern browsers support it both ways, since tons of sites use
:beforeand browsers really value backwards compatibility.
- Hey it’s one less character as a bonus.
I’ve heard people say that they have a CSS linter that requires (or automates) them to be single-colon. Personally, I’m OK with people doing that. Seems fine. I’d value consistency over which way you choose to go.
On the flip side, there’s an argument for going with
::before that goes like this:
- Single-colon pseudo-elements were a mistake. There will never be any more pseudo-elements with a single-colon.
- If you have the distinction straight in your mind, might as well train your fingers to do it right.
- This is already confusing enough, so let’s just follow the correctly specced way.
I’ve got my linter set up to force me to do double-colons. I don’t support Internet Explorer 8 anyway and it feels good to be doing things the “right” way.