-
Notifications
You must be signed in to change notification settings - Fork 707
[selectors] Let :is() have better error-recovery behavior than normal Selectors #3264
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
Comments
Shouldn't this belong to |
@CyberAP, the point is to avoid having to write the same rules twice (for new and all browsers). For example, consider a menu that is by default .menu:hover, .menu:focus-within { transform: none; } ...but in browsers that don't support However, with the new proposal, the following hypothetical example :is(.menu:hover, .menu:focus-within, :current(.menu)) { transform: none; } would be able to work in browsers that already support How can this be solved with |
@SelenIT, thanks for a great explanation! That does make sense and actually is a really great feature I would like to have. |
You mean like #3082, except without the vendor prefix exemption? |
Yes, and safely; I'm pretty sure we can't do #3082. |
The CSS Working Group just discussed
The full IRC log of that discussion<dael> Topic: Let :matches() have better error-recovery behavior than normal Selectors<dael> github: https://github.com//issues/3264 <dael> Rossen: Is TabAtkins on? <dael> fantasai: I can take it <dael> fantasai: When we have a list of selectors :foo, :bar <dael> fantasai: Browser doesn't rec :foo so the entire style rule is thrown out <dael> fantasai: That's selectors invalidation. <dael> fantasai: Other style of invalidation is media queries-like where you throw out a section. So if you have foo, screen we recognize screen <dael> fantasai: Can't do MQ like because it would break the web for selectors. TabAtkins pointed out we have ability to do it within the new selectors in L4 <dael> fantasai: Issue proposes we adopt MQ-like invalidation inside the pseudoclasses that take selectors. <dael> fantasai: :foo || :bar, [known selector] we'd only do the part we recognize. <dael> fantasai: Makes a lot os sense to me together with @supports rule we added. Gives authors much better tools. If they want more granular they can use something else <dael> Rossen: Sounds reasonable. <dael> Rossen: Opinions? <dael> myles: Thoughts from people that teach this? Seems like could be confusing <dael> Rossen: leaverou or rachelandrew ? <dbaron> Were you suggesting doing different things for :matches() vs. :is() ? <tantek> agreed with myles, it could be confusing. would definitely want webdev teacher feedback on this. <dael> fantasai: dbaron this was from before we renamed. Title should be is. Applies to is, not, has, nth-child, and maybe current <dael> dbaron: One worry is some have been around for a while and might have compat issues <dael> fantasai: :not with commas isn't widely supported. <dael> fantasai: Not with a single argument that's invalid makes the whole thing invalid <dael> florian: I think not with a comma is supported in Safari and Viviostyle <dael> fantasai: Not is trickier because it's a negation <dael> leaverou: Trying to decide error recovery or syntax? <dael> fantasai: Error recovery <dael> leaverou: Sounds amazing thing to do. It might be a little confusing, but it's worth it. In talks I only use webkit version and have to mention verbally it's just webkit. As an author I would love it <dael> emilio: Doesn't solve unknown pseudo elements issue, right? <dael> fantasai: No, sep. <dael> emilio: I think that's biggest issue authors want to solve <dael> fantasai: There's a rule for the webkit <dael> emilio: Want to style a video control for webkit and edge it's not stanard. That's the biggest source of duplication <dael> fantasai: This would solve, put it in all one :is <dael> emilio: Syntax allow psuedo elements inside? <bradk> I’m still concerned about :not. Can we find out how much authors have :-webkit and commas inside not? <dael> fantasai: This is work for pseudo classes. Elements is next on agenda <florian> I support this <dael> Rossen: bradk point about not and his concern, can we address that now? <dael> Rossen: Concern is the :not and defining how much authors have commas inside a not? <dael> florian: It's safari only <dael> bradk: Safari on iphone is used a lot. :not has been without commas for a while, but it's used in mobile web a lot. That's my suggestion, I'd like actual data <dael> florian: This is hard data to get. Need to find usage that would break the page if it started working in a different way. That's a judgement call <dael> Rossen: Another way to ask is if any Apple folks have an issue with this. If they feel comfortable with compat risk we can resolve <dael> bradk: That solution would be okay <dael> smfr: I don't think we have enough [missed] <dael> smfr: I don't thinkw e have enough information to know. When we impl :not we got compat issues b/c people using it in wrong ways <dael> smfr: No feeling for how common comma use is to know if it's risky <dael> Rossen: Would you be okay with current proposal in the absense of this information? <dael> smfr: I think so <dael> Rossen: Anything else before we try and resolve? <bradk> No strong objection <dael> fantasai: Use media query style invalidation inside psuedo classes that accept selector lists <dael> Rossen: Objections to ^? <dael> emilio: Would like behavior for :not clarified <dael> fantasai: Makes sense <dael> RESOLVED: Use media query style invalidation inside pseudo classes that accept selector lists <dael> Rossen: fantasai and TabAtkins will have clarification in spec |
emilio pointed out that we need to be careful about how we handle A related question is |
The thing about Also, at least for unknown pseudo‑classes, we could have those match nothing, so |
I agree that we could minimize the Web-compat risk by saying that error recovery only applies if two or more selectors are supplied.
This would have the following benefits:
As a minor variation, preserving the same benefits, we could say that error recovery only applies if at least one of the selectors is valid. Then
This might be easier to teach, and avoid developers' confusion when they see an introduced |
That should probably only apply to Also, it might be a good idea to still parse |
CSS Selectors 4 allows :not to accept selector lists. There is a proposal for invalid complex selectors in the list to be ignored (instead of causing the whole selector to fail parsing. This would affect :is :where :nth-child :nth-last-child, :has and :not, with the main compatibility risk being :not. w3c/csswg-drafts#3264 We add use counters to estimate the Web compatibilty risk. BUG=568705 Change-Id: I708d48d626a6e61cc8c1076d40d2c33bb19496e3 Reviewed-on: https://chromium-review.googlesource.com/c/1354751 Reviewed-by: Rune Lillesveen <futhark@chromium.org> Commit-Queue: Eric Willigers <ericwilligers@chromium.org> Cr-Commit-Position: refs/heads/master@{#612177}
For kCSSSelectorNotWithValidList kCSSSelectorNotWithInvalidList kCSSSelectorNotWithPartiallyValidList |
We haven't discussed what dev tools, etc., should show when the author provided |
I think displaying it as |
The CSS Working Group just discussed
The full IRC log of that discussion<presenter> Topic: Error recovery for :is() and :not()<astearns> github: https://github.com//issues/3264 <presenter> ewilligers: We resolved we'd like to have error-recovery for :is() and :where(), but unsure about :not(). <presenter> ewilligers: I have use-cases showing that :not() is used frequently, so we probably don't want to change the meaning. <presenter> ewilligers: Do we want :nth-child() or :nth-last-child() have error-recovery? <presenter> fantasai: nth-child should probably have the same error-recovery as :is() <florian> fantasai: I think it would make more sense with compound, not complex selectors <presenter> fantasai: The big question for nth-child was compound vs complex selectors. <florian> fantasai: people want that <presenter> fantasai: If that makes it easier, would be good. Things like zebra-striping non-hidden rows. <presenter> ewilligers: I think webkit already shipped complex selectors in nth-child <fantasai> s/good/good to get it implemented faster/ <fantasai> s/rows/rows is a major use case that's not currently solved otherwise/ <presenter> dydz: I'm looking in the WK code <presenter> fantasai: Emilio asked why we need selectors in :nth-child() <presenter> fantasai: Say we have a list of items, I want to color their backgrounds alternating <presenter> fantasai: But some of them are hidden; they're display:none <presenter> fantasai: Counting is based on sibling list. If you hide 3rd one, 2nd and 4th will both have the same color <presenter> fantasai: So want to count after filtering <presenter> emilio: Whew, that's gonna be slow. We have a lot of caching already to make :nth-of-type() fast. <presenter> ewilligers: I confirmed that Safari supports :nth-child(even of div+div) <presenter> fantasai: My main concern is if other impls are more likely to implement without complex selectors, getting even compound-selector interop would still be great. <presenter> emilio: I think impl-wise, not supporting complex selectors is easier. <presenter> TabAtkins: Unless we recursively pass down the compound-only restriction into :is()/etc, you're at full power anyway. <presenter> fantasai: Maybe that's reasonable to have that sort of restriction. <tantek> agreed. reasonable restriction <presenter> emilio: Did we decide on how the new error recovery behavior serializes. <fantasai> fantasai: We'll just say Safari supports L5 of selectors, and L4 doesn't accept combinators <presenter> emilio: Did we decide about serialization of invalid selectors in :is()? <presenter> TabAtkins: I didn't think we were doing anything in particular? <presenter> ewilligers: I thought we'd just drop them. <presenter> emilio: What if they're all invalid? <presenter> ewilligers: You just get :is(). A little weird with :nth-child(even of), tho. <presenter> ewilligers: What about parsing of weird stuff? Extra close brackets, what happens? <presenter> TabAtkins: Syntax already handles brackets correctly. We just split the tokens on top-level commas, then interpret each chunk as a selector. <presenter> fantasai: So back to the issue: :is() and :not() take a list of selectors <presenter> fantasai: Currently any invalid selector invalidates the entire selector list. <presenter> fantasai: Because we now have these functional notations that creates some scoping, within :is() we can just ignore in the invalid selector, but still process the rest. <presenter> fantasai: So we're gonna resolve that within :is(), we ignore invalid selectors. <presenter> ewilligers: And :where(), :nth-child(), :has(), etc. <presenter> fantasai: But not in :not() - the whole thing will invalidate if any are any invalid. <presenter> gregwhitworth: I think it's weird to have :not() work different. I get the %s making it hard tho. <presenter> AmeliaBR: I do use :not() as an @supports for new selectors... <fantasai> AmeliaBR: e.g. :not(:valid) means you support :valid, and this selector selects things that are not valid <presenter> TabAtkins: I was going over the boolean logic for :not() invalidating just parts too this morning, and was getting really confused... <presenter> RESOLVED: Drop individual invalid selectors from selector lists in *all* selector functions that take such lists, *except* for :not(). |
This reverts the use counters added in https://chromium-review.googlesource.com/c/chromium/src/+/1354751 The CSS Working Group was considering allowing :not() to ignore selectors that are invalid or not accepted by the browser. Use counts showed that this would affect a large percentage of pages w3c/csswg-drafts#3264 (comment) and so the decision was made to not change the behavior of :not w3c/csswg-drafts#3264 (comment) Data collection is no longer required. BUG=568705 Change-Id: I38ddaee5339e19b70c1c13c9507a50ae27c354b0 Reviewed-on: https://chromium-review.googlesource.com/c/1487753 Commit-Queue: Emil A Eklund <eae@chromium.org> Reviewed-by: Emil A Eklund <eae@chromium.org> Cr-Commit-Position: refs/heads/master@{#635559}
CSS Selectors 4 allows :not to accept selector lists. There is a proposal for invalid complex selectors in the list to be ignored (instead of causing the whole selector to fail parsing. This would affect :is :where :nth-child :nth-last-child, :has and :not, with the main compatibility risk being :not. w3c/csswg-drafts#3264 We add use counters to estimate the Web compatibilty risk. BUG=568705 Change-Id: I708d48d626a6e61cc8c1076d40d2c33bb19496e3 Reviewed-on: https://chromium-review.googlesource.com/c/1354751 Reviewed-by: Rune Lillesveen <futhark@chromium.org> Commit-Queue: Eric Willigers <ericwilligers@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#612177} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 7f276c9a8d885ab388eb17cf4e00f54974d46715
This reverts the use counters added in https://chromium-review.googlesource.com/c/chromium/src/+/1354751 The CSS Working Group was considering allowing :not() to ignore selectors that are invalid or not accepted by the browser. Use counts showed that this would affect a large percentage of pages w3c/csswg-drafts#3264 (comment) and so the decision was made to not change the behavior of :not w3c/csswg-drafts#3264 (comment) Data collection is no longer required. BUG=568705 Change-Id: I38ddaee5339e19b70c1c13c9507a50ae27c354b0 Reviewed-on: https://chromium-review.googlesource.com/c/1487753 Commit-Queue: Emil A Eklund <eae@chromium.org> Reviewed-by: Emil A Eklund <eae@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#635559} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 6b9a6186caaf4b814b297d2e3f7fe3d22c3b6eff
What should happen if someone were to write: :is(h1, h3), :is(h2:maybe-unsupported) { font-family: sans-serif } I believe that it should be treated as if the following was written in browsers that don't support :is(h1, h3) { font-family: sans-serif } |
I'm all for this, but it will interact surprisingly with selector nesting, since It makes nesting for |
Drive-by comment: seems that in Firefox 78+, and the upcoming Safari 14 (currently in the Technology Preview stage), the |
Agenda+ to look into the problem raised by #3264 (comment), and to consider whether compat is starting to paint us into a corner here. |
I'm happy to implement this in Gecko if people define in the spec how to deal with the empty-selector behavior. Like, should Also, it may be a bit confusing if people write stuff like |
Then, of course |
Yes, I was going to serialize Is serialization of selectors web exposed, i.e. testable in WPTs? |
@ewilligers Sure, include test_valid_selector(":is(:nonsense)", ":is()"); |
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: [selectors] Let :is() have better error-recovery behavior than normal Selectors<dael> github: https://github.com//issues/3264 <dael> ericwilligers: We resolved to have better error recovery but WK shipped without and FF is about to. Is it too late or do we still want error recovery? <dael> TabAtkins: If possible I'd like to have it. If we have to oh well, but it's bad behavior without <dael> ericwilligers: Who wants to do spec update? <dael> ericwilligers: We resolved on issue but spec isn't updated <dael> TabAtkins: I'll do it if we agree today to proceed <dael> Rossen_: We're wanting to hold previous resolution that requires error recovery and make that edit into spec? Or are we trying to relax the error recovery and not proceed with edits? <dael> ericwilligers: [missed] <dael> ericwilligers: I'm propsing the first, that we go ahead and make edit. <dael> Rossen_: You're proposing add it to spec and pester impl to do that <dael> ericwilligers: Yes <astearns> notes that Emilio says he's OK implementing it <dael> Rossen_: Alright. Any thoughts on that? Are we still committed and have TabAtkins add edits? <dael> TabAtkins: We'd need FF or WK dev to be okay doing change <dael> Rossen_: emilio is signaling he's fine with change. Only WK is going to be required to update. Anyone from WK on? <dael> smfr: If emilio is fine changing we're fine changing <dael> Rossen_: We have a resolution to do error recovery. Do we need resolution to have TabAtkins edit it in? <dael> Rossen_: We'll close no change but to put in the required edits <dael> Rossen_: Thank you |
https://bugzilla.mozilla.org/show_bug.cgi?id=1664718 is the Gecko bug for this (sorry for the lag, busy month!). I plan to enable it on Nightly and beta for now to collect potential breakage, but will enable after a couple releases everywhere if there's no issue. |
Just verifying as I write the spec - in #3264 (comment) @ewilligers suggested that we handle "single selector, which is invalid" differently from the rest of the cases, since that has legacy implications, but it looks like we're no longer doing that? That is, |
… and :where(). (Per WG resolution, we dont' use it in :not().) #3264
Yes, that's what I implemented, fwiw. I don't see why "single invalid selector" should be different. |
Cool, then please make sure the spec edits linked above are satisfactory; they apply to :is(), :where(), and :has(), but not :not(), per resolutions earlier in the thread. |
They look good. I'd probably note that there's an interesting side-effect of this behavior which I'm not sure it's great, which is that the specificity of |
Yeah, unless I distinguish between "parsable, just using unknown selectors" and "lol wtf is this", I can't handle that. And even then, a "parsable but unknown" selector might have complex specificity behavior, so we actually can't even predict that. So it's just something we'll have to accept. |
…elector parsing, per original resolution. #3264
This isn't captured in the current spec, but I remember earlier speculation that we could use
:matches()
as a way to get around the bad Selectors behavior of "a syntax error in one complex selector invalidates the whole sequence" that we're stuck with. Do we still think this is a worthwhile idea to pursue?Spec-wise, what this would mean is defining the official syntax as
:matches( <any-value> )
, then split the result on top-level comma tokens, then attempt to parse each item as a<complex-selector>
, and just ignore any invalid ones. (If all of them are invalid, the selector matches nothing.)Then, if you're concerned about using a newer feature, you can just write your selectors like:
An unfortunately, but relatively minor, tax for getting better error-recovery behavior. (If we do end up renaming it to
:is()
, it's even more minor.)The text was updated successfully, but these errors were encountered: