Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-selectors] Reconsider removing selector list invalidation #3082

Open
ExE-Boss opened this issue Sep 5, 2018 · 8 comments
Open

[css-selectors] Reconsider removing selector list invalidation #3082

ExE-Boss opened this issue Sep 5, 2018 · 8 comments

Comments

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Sep 5, 2018

https://drafts.csswg.org/selectors-4/#grouping

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 selector list would be invalid. This would invalidate the rule for all three heading elements, whereas in the former case only one of the three individual heading rules would be invalidated.

I wasn’t aware of that for a long time and wrote many of my stylesheets with the assumption that a single unknown selector in a selector list wouldn’t invalidate the whole selector list12.

Even in the specification, global selector list invalidation is said to be considered a legacy mistake in appendix B.

I propose to run a web study, similar to what Chrome did in #2156 to see if this very dumb3 legacy mistake can be fixed by getting rid of selector list invalidation.

Footnotes

  1. An actual selector list I once wrote:

    /* The `[data-ie]` attribute contains the string "legacy" for IE8 or older,
       and IE8 only supports the single‑colon `::before`/`::after` syntax */
    html[data-ie~="legacy"] pre.line-numbers:before,
    pre.line-numbers::before {
    	content: "1\A 2\A 3\A 4\A 5\A 6\A 7\A 8\A 9\A 10…"; /* all the way up to 9999 */
    }
    
  2. Current known issues caused by this legacy mistake:

  3. Yes, I have a very strong opinion about this.

@SelenIT
Copy link
Collaborator

SelenIT commented Sep 5, 2018

Please consider that the existing behavior is sometimes used as a hack to selectively target a specific browser. For example, people sometimes use selectors like

x:-moz-any-link, .selector { /* this should apply only in Firefox */ } 
_:-ms-input-placeholder, .selector { /* this should apply only in IE10+/Edge */ }

These styles are usually intended to counter some specific browser bugs, so they rely on the presence of this bug in the target browser, and on the absence of these style in other browsers. Exposing such styles to browsers that don't have these bugs would be not web-compatible.

The ::-webkit-craziness case was kind of special because there was time when many web apps (especially mobile ones) were made under assumption that non-WebKit-derived browsers nearly don't exist (at least in mobile world). That forced other browsers to start supporting some -webkit-prefixed features, and eventually even led to the creation of the Compatibility Standard.

@ExE-Boss
Copy link
Contributor Author

ExE-Boss commented Sep 5, 2018

Please consider that the existing behavior is sometimes used as a hack to selectively target a specific browser. For example, people sometimes use selectors like

x:-moz-any-link, .selector { /* this should apply only in Firefox */ } 
_:-ms-input-placeholder, .selector { /* this should apply only in IE10+/Edge¹ */ }

I am aware of that, that’s why I want to run the web study first.

Also, I have yet to actually run into a website using that.


¹ That won’t work in Edge, as Edge doesn’t support :-ms-input-placeholder

@SelenIT
Copy link
Collaborator

SelenIT commented Sep 5, 2018

Oops, thanks for the correction!

@jonjohnjohnson
Copy link

#3051

@SelenIT
Copy link
Collaborator

SelenIT commented Sep 6, 2018

If we have already started to distinguish the pseudo-elements that don't invalidate the selector list from those that do on a per-prefix basis, maybe it would work the other way round: treat all unknown pseudo-elements as (potentially) valid, except those starting with any prefix other than -webkit-?

From the first glance, this should not break the backwards compatibility, since the most cases of selector-based hacks would be covered with this exception. In the same time, this would allow to add new features in the stylesheets without need to separate things like

.panel:hover, .panel:focus-within { /* styles when the panel is activated by either the mouse or the keyboard */ }

into separate rules (as we have to do currently).

@ExE-Boss
Copy link
Contributor Author

ExE-Boss commented Sep 6, 2018

That sounds like a good idea to me.

Also, add pseudo‑classes to the mix as well, since your example uses pseudo‑classes and it would fix the issue with dumb CSS minimisers merging :matches(…) and the equivalent non‑:matches(…) rules together, which breaks on browsers that don’t support :matches(…) (i.e. anything that (as always) isn’t WebKit‑based)

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Reconsider removing selector list invalidation, and agreed to the following:

  • RESOLVED: kick the can down the road and think about this for Selectors 5
The full IRC log of that discussion <dael> Topic: Reconsider removing selector list invalidation
<dael> github: https://github.com//issues/3082
<dael> fantasai: Closely related issue
<dael> fantasai: We were talking about how invalidation is a problem, can't change for compat reasons.
<dael> fantasai: Suggestion was have a special rule for unknown pseudo elements to treat as valid, but only for not prefixed ones. Wanted to ask WG if we should look into this
<dael> fantasai: If you don't recognize anything in the selector you invalidate the whole thing. Can't change whole rule, but maybe possible to change that rule only for pseudo elements
<dael> fantasai: Wanted to ask if anybody has thoughts on if this is something we should look into
<dael> Rossen: Opinions?
<dael> florian: I think people rely on it not to work as a form of browser sniffing
<dael> dbaron: Also one where I would ask who would impl first
<dael> Rossen: I'm hearing pushback
<dael> emilio: Assume proposal you need to work for unprefixed, right?
<dael> fantasai: Yes
<fantasai> s/for unprefixed/only for unprefixed/
<emilio> dbaron: sorry, too much noise here today :(
<dael> florian: Then it's a question of accidentally relying on it not to work. Possibly less but have no data.
<dael> Rossen: I can't figure out if this is something we want to work on or if just table
<dael> Rossen: Still hearing more pushback then interest
<dael> florian: If we could make it work it would be great.
<dael> fantasai: Want to know if we should a, accept b, reject or c, not now, maybe selectors 5
<dael> Rossen: Easiest to agree on is C
<bradk> C
<dael> Rossen: Anyone pushing for accept or reject?
<dael> Rossen: Objections to kick the can down the road and think about this for Selectors 5?
<bradk> Kick the can to the table
<dael> RESOLVED: kick the can down the road and think about this for Selectors 5
<dael> florian: Not satisfactory but until someone volunteers to collect data there's not much we can do.
<dael> Rossen: It's reflecting reality, though.

@claudepache
Copy link
Contributor

Gentle reminder that, beside making developer’s life more interesting, selector list invalidation blunder rule causes real breakage. Recently read in a Stackoverflow comment, working around ::backdrop not inheriting from any element,

:root, ::backdrop { --color-backdrop: red; }

and not realising that it breaks not only legacy browsers, but also latest (at time of writing) Safari, whoops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants