Why Isn't It Possible to Combine Vendor-Specific Pseudo-Elements/Classes into One Rule Set

Why isn't it possible to combine vendor-specific pseudo-elements/classes into one rule set?

CSS2.1 states:

The selector (see also the section on selectors) consists of everything up to (but not including) the first left curly brace ({). A selector always goes together with a declaration block. 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.

Note that since CSS2.1 pre-dates CSS3, "it is not valid CSS 2.1" is written under the assumptions that a user agent is fully CSS2.1-compliant and that CSS3 does not exist in theory. In practice, wherever the spec says "it is not valid CSS" or something to that effect, it should be taken to mean "it is not understood by the user agent". See my answer to this related question for a more in-depth explanation.

Namely, since one vendor's browser doesn't understand other vendors' prefixes, it has to drop any rules that contain those unrecognized prefixes in pseudo-class and pseudo-element selectors.1

For some insight as to why such a rule was put in place, see this answer.


1 Note that WebKit is notorious for partially flouting this rule: it has no trouble parsing rules whose selectors have unrecognized prefixed pseudo-elements (which in this case is ::-moz-placeholder). That said, the :-moz-placeholder pseudo-class in your combined rule will cause it to break anyway.

Why can't I combine pseudo-element selectors?

You are combining multiple vendor-specific selectors into a single CSS rule.

This means that if one of the selectors is not recognised by the browser, the entire CSS block is ignored. In this particular case, Chrome does not recognize ::-moz-range-track, because it is specific to Firefox/Gecko. This is not a quirk, but intended behaviour and part of the CSS standard.

The solution would be to split the declarations. Like so:

.range2::-webkit-slider-runnable-track {
height: 6px;
border-radius: 3px;
border: 1px solid black;
}
.range2::-moz-range-track {
height: 6px;
border-radius: 3px;
border: 1px solid black;
}

Updated CodePen

Combined CSS selectors dont work?

See the warning in the spec:

A comma-separated list of selectors represents the union of all
elements selected by each of the individual selectors in the list.

Warning: the equivalence is true in this example because all the
selectors are valid selectors. If just one of these selectors were
invalid, the entire group of selectors would be invalid.

Then, the group of selectors doesn't work because each browser only accept its vendor prefix, but the other ones are invalid.

Chain CSS Pseudo Selectors

This happens because ::selection is a pseudo element. There's a good explanation for this here.

Can't combine selectors using commas in CSS

You can't use commas to combine vendor-prefixed selectors because when a browser encounters a selector it does not understand, that line is "thrown out." This is why it's necessary to break up vendor prefixes for any selector, not just the :: pseudo-classes.

Here's a link to a CSS-Tricks comment on the problem.

Stylelint selector-max-specificity: class::placeholder (0,0,1) doesn't but class:focus::placeholder (0,1,1) throws error with 0.2.0 max specificity

Does anyone know why I get the error

Using this calculator you can see that the selector .input-basic__input--active:focus::placeholder has a specificity of 0,2,1, i.e. 2 (pseudo-)classes and 1 (pseudo-)element.

0,2,1 is greater than chosen max specificity of 0,2,0, and the rule correctly reports this.

You should increase your primary option to 0,2,1 if you want to use this selector.

the problem is that when I use wonderful-input::placeholder it doesn't throw me an error

The selector wonderful-input::placeholder has a specificity of 0,0,2, i.e. 2 (pseudo-)elements, which is lower than 0,2,0 so the rule allows it.

can I decrease the specificity on this one?

There is no way to decrease the specificity of the .input-basic__input--active:focus::placeholder selector and have it do the same thing: i.e. style the placeholder pseudo-element of focused elements that have the class input-basic__input--active.

I am trying to reduce CSS specificity in my project by using the stylelint selector-max-specificity

It's an admirable goal. You can also use the other selector-max-* rules, like selector-max-class, selector-max-combinators, selector-max-compound-selectors and so on, to help you do this.

Why can't I combine ::selection and ::-moz-selection in one CSS rule?

This is from the documentation:

Gecko is the only engine requiring the prefix. Due to the fact that
the CSS parsing rules require dropping the whole rule when
encountering an invalid pseudo-element, two separate rules must be
written: ::-moz-selection, ::selection {...}. The rule would be
dropped on non-Gecko browsers as ::-moz-selection is invalid on them.

https://developer.mozilla.org/en-US/docs/Web/CSS/::selection

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

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.

How to refactor input placeholder class?

tl;dr: the classes with those pseudo-selectors have to be seperate.

Explanation:

Refactoring the CSS in that way is not possible. It has to do with the way the pseudo elements for the specific vendors work. Since one vendor's browser doesn't "get" the prefixes of the other browsers, it disregards any rules that contain unrecognized prefixes in pseudo-class/element selectors.

From the docs:

4.1.7 Rule sets, declaration blocks, and selectors

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.



Related Topics



Leave a reply



Submit