What's difference between this two selectors? - css

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.

Related

How does the _:-ms-lang(x) fix for Edge and IE work?

I had a situation where I had to apply a specific CSS style in Edge and IE browsers only. I found online that you can prepend your CSS selector with _:-ms-lang(x) and the style will only be applied in IE and Edge.
But I wonder, how exactly is this fix working? As far as I know, the comma will just separate different selectors, meaning that other browsers should also interpret and use this style.
Here is an example:
Let's say we want to apply a width of 94px to .selector element only in Edge and IE.
_:-ms-lang(x), .selector {
width: 94px;
}
The Edge browser will apply this style, and others won't. But why not?
The comma in the selector should apply the style to _:-ms-lang(x) element AND to .selector element.
Here is a source for this IE hack.
And one more.
In CSS, when a browser does not recognize part of a selector (or thinks there is an error in a selector), it completely ignores the entire rule.
Here's the section in the CSS3 spec outlining this behavior
The prelude of the qualified rule is parsed as a selector list. If this results in an invalid selector list, the entire style rule is invalid.
Here CSS2.1 talks about the special case of comma
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.
Therefore when the other browsers try to parse the selectors, they find the _:-ms-lang(x) selector to be invalid and so ignore the entire rule (including .selector)
Also here is an excellent answer on why this behavior is desirable

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.

In CSS, what is the difference between ::first-letter and :first-letter?

Running through some test preparation, I was asked if this would set the first letter color correctly:
td.one::first-letter {
color:blue;
}
Now, I know I've seen places where the colon is doubled-up on, but a test jsFiddle doesn't show any difference in behavior between that and
td.two:first-letter {
color:green;
}
So, I'm just curious what the difference is, and why you would use :: instead of : in front of the pseudo-class?
http://jsfiddle.net/mori57/bqE7Q/
Checked the spec?
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.
http://www.w3.org/TR/selectors/#pseudo-elements
They're equivalent in this case, but only because it's a pseudo-element, not a pseudo-class. The double-colon syntax was created in order to prevent the confusion arising from calling single-colon pseudo-elements "pseudo-classes" (which your question demonstrates, oddly enough). From the spec:
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.
If you're not planning on supporting IE < 9, it is best to denote all your pseudo-elements with double colons going forward. If you require support for older versions of IE, you can continue using single colons, but only for the aforementioned selectors.

:after vs. ::after

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).

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