4

When combining pseudo-element selectors (for range inputs) I see that the styles are not applied. This forces me to separate my selectors and duplicate my CSS.

Does anyone know why this quirk occurs?

/* Keeping the selectors separate works */
.range1 {
  -webkit-appearance: none;
    -moz-appearance: none;
          appearance: none;
}
.range1::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 3px;
  border: 1px solid black;
}
.range1::-moz-range-track {
  height: 6px;
  border-radius: 3px;
  border: 1px solid black;
}

/* Combining the selectors fails */
.range2 {
  -webkit-appearance: none;
    -moz-appearance: none;
          appearance: none;
}
.range2::-webkit-slider-runnable-track,
.range2::-moz-range-track {
  height: 6px;
  border-radius: 3px;
  border: 1px solid black;
}

CodePen example.

Screenshot

oodavid
  • 2,148
  • 2
  • 23
  • 26

2 Answers2

9

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

Community
  • 1
  • 1
Baksteen
  • 1,235
  • 11
  • 25
  • Hmm, the spec states that "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." the selector itself is perfectly valid. After all it doesn't contain any troublesome characters. – oodavid May 29 '18 at 10:37
  • Although the selector doesn't contain weird characters and is a valid, working (in Firefox) selector. Chrome doesn't recognize it and marks it as invalid, thus ignoring the entire CSS rule. Alternatively, Firefox does not recognize the `-webkit-` selector, and thus marks the entire rule invalid too. In this case, browsers are not allowed to 'pick a winner' and apply the style to their specific implementation. – Baksteen May 29 '18 at 11:03
  • @oodavid: Vendor-specific features should be treated as not valid for the purposes of that part of the spec since they are non-standard after all. I just linked your question as a duplicate of one I answered, in which I state "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'." (I just edited my answer so that sentence is rewritten from an old one but the essence is the same.) – BoltClock May 30 '18 at 05:29
  • I see, it's a shame really as the _characters_ are valid. The invalid state is from failing to match a defined whitelist. As for "picking a winner", it's surely no different to having `.exists-in-dom, .doesnt-exist-in-dom`? – oodavid May 30 '18 at 07:13
  • Gee @BoltClock, I didn't find your answer on the website and I'm happy this answer is similar to yours :) oodavid, Take a look at [this answer](https://stackoverflow.com/a/13831877/) as to *why* this behaviour occurs. – Baksteen May 30 '18 at 09:09
  • @oodavid: That's true. The WG did consider relaxing the rules so that things that could parse but were simply unrecognized would simply match nothing instead of breaking the entire rule, but even that was dropped as it would break sites that rely on this behavior. (This is mentioned as well in the link above.) – BoltClock May 30 '18 at 09:18
  • Thanks both - I'd not considered the "comma" issue as in the linked article. The WG have a tough job! – oodavid May 30 '18 at 09:36
0

I think user agent doesn't recognize pseudo-element selector because it should starts with a { here in your case you are combining multiple selectors so it doesn't work for some/all browsers.

A selector always goes together with a {}-block. When a user agent can't parse the selector (i.e., it is not valid CSS3), it must ignore the {}-block as well.

https://www.w3.org/TR/CSS21/syndata.html#rule-sets

The selector 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.

Znaneswar
  • 3,329
  • 2
  • 16
  • 24