Should I use single colons (:) or double colons (::) for before, after, first-letter and first-line pseudo-elements?
For what it's worth, Selectors 4 now explicitly instructs1 authors to use double colons for all pseudo-elements, including CSS1 and CSS2 pseudo-elements, going forward (emphasis mine):
Because CSS Level 1 and CSS Level 2 conflated pseudo-elements and pseudo-classes by sharing a single-colon syntax for both, user agents must also accept the previous one-colon notation for the Level 1 & 2 pseudo-elements (
::before
,::after
,::first-line
, and::first-letter
). This compatibility notation is not allowed any other pseudo-elements. However, as this syntax is deprecated, authors should use the Level 3+ double-colon syntax for these pseudo-elements.
This means that the only appropriate use of the single-colon syntax today is if you absolutely require legacy browser support — the only browser that matters here is IE8 and older. If you don't, you should use the double-colon syntax for the sake of consistency with newer pseudo-elements which will only accept double colons. Besides, it's quite pointless to use the single-colon syntax if, for instance, you're going to apply properties that aren't supported by IE8 anyway, such as border-radius
or box-shadow
, to your ::before
and ::after
pseudo-elements.
I'd like to believe that Selectors 3 at the very least implied this in its statement that the single-colon syntax does not apply to any newer pseudo-elements, but having this sort of thing stated in black and white never hurt anybody and it's good to know that the upcoming standard does just that.
Also, there is absolutely no reason to write duplicate rules with both notations in the same stylesheet (e.g. :before, :after { ... } ::before, ::after { ... }
), as no browser in existence supports the new syntax without supporting the older one.
1 I say this fully aware that it probably didn't state this yet at the time this question was asked — the May 2013 WD certainly did not.
Should I use single or double colon notation for pseudo-elements?
Do not use both combined with a comma. A CSS 2.1 compliant (not CSS3 capable) user agent will ignore the whole rule:
When a user agent cannot parse the selector (i.e., it is not valid CSS 2.1), it must ignore the selector and the following declaration block (if any) as well.
CSS 2.1 gives a special meaning to the comma (,) in selectors. However, since it is not known if the comma may acquire other meanings in future updates of CSS, the whole statement should be ignored if there is an error anywhere in the selector, even though the rest of the selector may look reasonable in CSS 2.1.
http://www.w3.org/TR/CSS2/syndata.html#rule-sets
You could however use
.foo:after { /*styles*/ }
.foo::after { /*styles*/ }
On the other hand this is more verbose than necessary; for now, you can stick with the one-colon notation.
What is the difference between pseudo-classes and pseudo-elements?
From https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Pseudo-classes_and_pseudo-elements
Pseudo-class :
A CSS pseudo-class is a keyword, preceded by a colon (:), added to the end of selectors to specify you want to style the selected elements, and only when they are in certain state. For example, you might want to style an element only when it is being hovered over by the mouse pointer, or a checkbox when it is disabled or checked, or an element that is the first child of its parent in the DOM tree.
Examples:
- :active
- :checked
- :nth-child()
- :first
- :hover
Pseudo-elements ::
Pseudo-elements are very much like pseudo-classes, but they have differences. They are keywords, this time preceded by two colons (::), that can be added to the end of selectors to select a certain part of an element.
Examples:
- ::after
- ::before
- ::first-letter
- ::first-line
- ::selection
- ::backdrop
As stated by @stephanmg:
In practice ::before is used as :before and ::after is used as :after
because of browser compatibility. Both are pseudo-elements, but may
look like pseudo classes. This might be confusing if you read CSS
code.
Why are there two colons here? span::before
It's a pseudo-element, as defined by the CSS Selectors Level 3 spec:
The
::before
and::after
pseudo-elements can be used to describe generated content before or after an element's content.
It is effectively the same as the single-colon syntax defined by the level 2 spec. The level 3 spec introduces an extra colon to differentiate between pseudo-elements and pseudo-classes (which use a single colon).
Both syntaxes will work in newer browsers, but older browsers will not recognise the newer ::
style.
For even more detail, you can look at the grammar from the level 3 spec, which states:
'::' starts a pseudo-element, ':' a pseudo-class
Should I use single colons (:) or double colons (::) for before, after, first-letter and first-line pseudo-elements?
For what it's worth, Selectors 4 now explicitly instructs1 authors to use double colons for all pseudo-elements, including CSS1 and CSS2 pseudo-elements, going forward (emphasis mine):
Because CSS Level 1 and CSS Level 2 conflated pseudo-elements and pseudo-classes by sharing a single-colon syntax for both, user agents must also accept the previous one-colon notation for the Level 1 & 2 pseudo-elements (
::before
,::after
,::first-line
, and::first-letter
). This compatibility notation is not allowed any other pseudo-elements. However, as this syntax is deprecated, authors should use the Level 3+ double-colon syntax for these pseudo-elements.
This means that the only appropriate use of the single-colon syntax today is if you absolutely require legacy browser support — the only browser that matters here is IE8 and older. If you don't, you should use the double-colon syntax for the sake of consistency with newer pseudo-elements which will only accept double colons. Besides, it's quite pointless to use the single-colon syntax if, for instance, you're going to apply properties that aren't supported by IE8 anyway, such as border-radius
or box-shadow
, to your ::before
and ::after
pseudo-elements.
I'd like to believe that Selectors 3 at the very least implied this in its statement that the single-colon syntax does not apply to any newer pseudo-elements, but having this sort of thing stated in black and white never hurt anybody and it's good to know that the upcoming standard does just that.
Also, there is absolutely no reason to write duplicate rules with both notations in the same stylesheet (e.g. :before, :after { ... } ::before, ::after { ... }
), as no browser in existence supports the new syntax without supporting the older one.
1 I say this fully aware that it probably didn't state this yet at the time this question was asked — the May 2013 WD certainly did not.
Does pseudo first-line need double colon syntax?
As MDN states:
In CSS 2, pseudo-elements were prefixed with a single colon character.
As pseudo-classes were also following the same convention, they were
indistinguishable. To solve this, CSS 2.1 changed the convention for
pseudo-elements. Now a pseudo-element is prefixed with two colon
characters, and a pseudo-class is still prefixed with a single colon.As several browsers already implemented the CSS 2 version in a release
version, all browsers supporting the two-colon syntax also support the
old one-colon syntax.If legacy browsers must be supported, :first-line is the only viable
choice; if not, ::first-line is preferred.
Further, as the W3 states:
This :: notation is introduced by the current document in order to
establish a discrimination between pseudo-classes and pseudo-elements.
For compatibility with existing style sheets, user agents must also
accept the previous one-colon notation for pseudo-elements introduced
in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
:after). This compatibility is not allowed for the new pseudo-elements
introduced in this specification.
CSS :: vs : -- pseudo-element vs pseudo-selector?
Pseudo-classes (:
) allow you to style the different states of an element e.g. when you hover over it, when it is disabled, when it is the first child of its parent, etc.
Pseudo-elements (::
) allow you to style different parts of an element e.g. the first line, the first letter, inserting content before or after, etc.
Originally they all used a single colon, but CSS3 introduced the double colon to separate the two.
What does the double colon (::) mean in CSS?
It means pseudo element selector. It means the element to the right doesn't exist in the normal DOM, but can be selected.
A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.
Source
It was originally only a single colon, but was changed to differentiate it from pseudo classes (like :hover
, :first-child
, :not
etc). It's best to use :
for before
and after
pseudo elements since the single colon has better browser support, namely in earlier IE versions.
:after vs. ::after
It's pseudo-class vs pseudo-element distinction.
Except for ::first-line
, ::first-letter
, ::before
and ::after
(which have been around a little while and can be used with single colons if you require IE8 support), pseudo-elements require double colons.
Pseudo-classes select actual elements themselves, you can use :first-child
or :nth-of-type(n)
for selecting the first or specific <p>
's in a div, for example.
(And also states of actual elements like :hover
and :focus
.)
Pseudo-elements target a sub-part of an element like ::first-line
or ::first-letter
, things that aren't elements in their own right.
Actually, better description here: http://bricss.net/post/10768584657/know-your-lingo-pseudo-class-vs-pseudo-element
Also here: http://www.evotech.net/blog/2007/05/after-v-after-what-is-double-colon-notation/
Related Topics
Why Does Stacking Order Change on Webkit Filter Hover
How to Make a Circle Around Content Using CSS
Set Position Absolute and Margin
Blocky Gradient Effect in CSS3
Continuous CSS Rotation Animation on Hover, Animated Back to 0Deg on Hover Out
CSS Display: Table Min-Height Not Working
Bootstrap Button Shows Blue Outline When Clicked
How to Apply Border Radius in IE8 and Below IE8 Browsers
Allowed Characters for CSS Identifiers
How to Change Color of Icons in Font Awesome 5
Prevent 100Vw from Creating Horizontal Scroll
Convert 8-Digit Hex Colors to Rgba Colors
Parent Element Backdrop-Filter Does Not Apply for Its Child
Float a Div Above Page Content
How to Have a Varying Number of Columns Per Row in a CSS Grid