:after vs. ::after - css

Is there any functional difference between the CSS 2.1 :after and the CSS 3 ::after pseudo-selectors (other than ::after not being supported in older browsers)? Is there any practical reason to use the newer specification?

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/

CSS Selectors like ::after are some virtual elements not available as a explicit element in DOM tree. They are called "Pseudo-Elements" and are used to insert some content before/after an element (eg: ::before, ::after) or, select some part of an element (eg: ::first-letter). Currently there is only 5 standard pseudo elements: after, before, first-letter, first-line, selection.
On the other hand, there are other types of selectors called "Pseudo-Classes" which are used to define a special state of an element (like as :hover, :focus, :nth-child(n)). These will select whole of an existing element in DOM. Pseudo classes are a long list with more than 30 items.
Initially (in CSS2 and CSS1), The single-colon syntax was used for both pseudo-classes and pseudo-elements. But, in CSS3 the :: syntax replaced the : notation for pseudo-elements to better distinguish of them.
For backward compatibility, the old single-colon syntax is acceptable for pseudo-elements like as :after (browsers still all support the old syntax with one semicolon). Only IE-8 doesn’t support the new syntax (use single-colon if you want to support IE8).

Related

why do some pseudo-elements seem like pseudo-classes?

pseudo-elements are like virtual elements, however it seems to me that many of them are more like classes than elements.
eg. ::PLACEHOLDER ::SELECTION ::FIRST-LINE ::FIRST-LETTER ::BACKDROP
Can someone explain to me how these are considered elements and not classes? They aren't creating any new elements, they are just applying a class in certain circumstances.
Pseudo-classes target an existing element when the state of it matches a condition.
You can target a and a:visited and they will match exactly the same "thing" when it is in the visited state.
Pseudo-elements target something that isn't an element in its own right. The :first-line of an element isn't event a complete DOM node.

Is there a difference in CSS selectors `:enabled` vs `not(:disabled)`

Is there a difference in behaviour or browser support for using the CSS3 selectors :enabled or not(:disabled)?
I expect them to be functionally identical, and as they are both CSS3 selectors, browser support should be identical too.
Yes, there is a difference — :not(:disabled) can match elements that are neither :enabled nor :disabled. These are elements where enabled/disabled semantics simply don't apply, such as div, p, ul, etc.
The spec confirms this:
What constitutes an enabled state, a disabled state, and a user interface element is language-dependent. In a typical document most elements will be neither :enabled nor :disabled.
Interestingly, the same can't be said for :checked — there is no corresponding :unchecked pseudo-class, despite the fact that not all elements have checked/unchecked semantics either. See my answer to this question.
If you're qualifying these pseudo-classes with a type selector (such as input, select or textarea) or a class selector, you probably don't have to worry about this. Still, it makes more sense to use :enabled than :not(:disabled).
Browser support for the majority of level 3 pseudo-classes is indeed identical — there are no known browsers that support either :enabled or :disabled only. However, according to MDN it looks like Opera 9.0 and Safari 3.1 don't support :not(), although they do support :enabled and :disabled, and some other features like substring-matching attribute selectors and the general sibling combinator ~ are supported in IE7 with some issues and a little bit better in IE8.

Should I use single colons (:) or double colons (::) for before, after, first-letter and first-line pseudo-elements?

From MDN:
The :: notation was introduced in CSS 3 in order to establish a
discrimination between pseudo-classes and pseudo-elements. Browsers
also accept the notation : introduced in CSS 2.
If the notation : will always be accepted by CSS3 browsers, should I use it because it works on old and new browsers?
Or should I use both of them, : for old browsers and :: for new ones, because the notation : won't be always accepted?
Note: I think my question isn't a duplicate isn't a duplicate of Should I use single or double colon notation for pseudo-elements? because the other question asks about single vs double notation for ALL pseudo-elements; while my question is only about pseudo-elements defined in CSS2, not the new ones defined in CSS3, because I already know that with those I must use ::.
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.
As I mentioned in this comment previously - http://css-tricks.com/html5-progress-element/#comment-533395
Short Answer – Use single colon notation :
Long Answer – There’s no real difference between :before and ::before, or between :after and ::after. But since the older browsers use a single colon notation, so using : is always a safer bet. Read this spec defined by W3C on pseudo elements which states that,
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 CSS level 3.
I would would go for the single :
People now a days should at least have somewhat of the latest browsers installed, so you have nothing to worry about.

What's difference between this two selectors?

I see two different style of define pseudo element like this:
#div::after { content: ''; display: block; }
#div:after { content: ''; display: block; }
What's the difference between them and what way should I used?
This distinguishes pseudo elements from pseudo classes. but actually they're the same except that the single colon : is used for CSS2 syntax when the double colon :: is introduced in CSS3. So if your concern is about browser compatibility, you should stick with :after
::after is the CSS 3 notation. This is recommended for use according to the Selectors Level 3 Module. The only issue with using the newer syntax is that you will run into IE7/8 compatibility problems
The point is also to distinguish pseudo-elements from pseudo-classes (which only use a single colon)
From Selectors Level 3:
"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."
They both do the same thing.
::after is more logical, but it isn't supported by older IEs
In general, :whatever is a pseudo-class – it filters the selector it's appended to to only match sometimes (eg, when hovered, or when invalid).
::whatever is a pseudo-element – it refers to a new virtual element related to the selector it's appended to; an element that does not actually exist in source (eg, a scrollbar).
before and after are logically pseudo-elements, but they were introduced before the :: syntax existed.
The :: designates that the psuedo used is targeting an additional dynamically created element is and not a restyling of an existing element. But because of backwards compatibility both the single and double colon are supported by browser vendors meaning in real terms they achieve the same results in modern browsers.

What is the difference between :before and ::before?

I just saw a CSS code that included ::before tag. I looked at MDN to see what the ::before is but I really didn't understand it.
Can someone explain how it works?
Does it make a DOM element before what we select by CSS?
According to those docs, they are equivalent:
element:before { style properties } /* CSS2 syntax */
element::before { style properties } /* CSS3 syntax */
The only difference is that the double colon is used in CSS3, whereas the single colon is the legacy version.
Reasoning:
The ::before notation was introduced in CSS 3 in order to establish a
discrimination between pseudo-classes and pseudo-elements. Browsers
also accept the notation :before introduced in CSS 2.
This distinguishes pseudo elements from pseudo classes.
The difference between pseudo classes and pseudo elements is described at http://www.d.umn.edu/~lcarlson/csswork/selectors/pseudo_dif.html
They essentially mean the same thing. The :: was introduced in CSS3 to help descriminate between pseudo elements (like :before and :after) and pseudo classes (like :link and :hover).
I checked out MDN and w3.org, and the best I could come up with is that :: is used for structural changes, and : is used for styling.
They are currently interchangeable for compatibility reasons.
It appears to separate :link (for instance), which styles a <a>, from :before (which is a structural change).
: is for styling, :: is for structure.
One is the CSS2 (:before) way and the other is CSS3 (::before). Currently they are interchangeable in browsers that support CSS2 & CSS3.
Here's a good explanation: http://www.impressivewebs.com/before-after-css3/

Resources