-
Notifications
You must be signed in to change notification settings - Fork 661
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
[selectors-4] Consider disallowing logical combination pseudo-classes inside :has() #6952
Comments
I disagree with "generally not very useful":
|
I'd like to provide some context for those web developers commenting or reacting that they don't like this idea and would prefer every possible combination of selector syntax be allowed. The reason browsers did not implement a parent selector many years ago is because there are some pretty alarming performance concerns. It could have been very easy to choke a browser from the 2000s, making a web page slow to an unusable state. In fact, even in the first half of 2021, we were still not sure it was possible to implement Everyone would love to implement This issue is for the CSSWG to discuss, as we figure out a way to create a selector that does what most developers need most of the time, without any bad consequences. Please don't give us a hard time about it. What we wish for and what we need to do because of reality don't always perfectly match. And it is looking terrific for an incredibly useful selector finally becoming reality, after years of pent up desire. |
I’d be fine with these limitations for |
One of use cases for |
To be clear, while I disagreed with these combinations not being useful, I'd fine with the limitations, for the reasons stated above. But, regarding |
I guess it's more important to get It's another question whether invalidating Also, I guess the question relates basically to all functional pseudo-classes accepting selector lists, so, if the limitation is needed, |
https://bugs.webkit.org/show_bug.cgi?id=235231 Reviewed by Dean Jackson. LayoutTests/imported/w3c: * web-platform-tests/css/selectors/has-argument-with-explicit-scope.tentative-expected.txt: * web-platform-tests/css/selectors/has-basic-expected.txt: * web-platform-tests/css/selectors/parsing/parse-has-expected.txt: Source/WebCore: Nested case ':has(:has(foo))' adds no meaningful capability and would complicate invalidation. See w3c/csswg-drafts#6952 for more details. * css/parser/CSSSelectorParser.cpp: (WebCore::CSSSelectorParser::consumePseudo): Also set m_resistDefaultNamespace like other logical combination pseudo-classes. * css/parser/CSSSelectorParser.h: Canonical link: https://commits.webkit.org/246125@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@288111 268f45cc-cd09-0410-ab3c-d52691b4dbfc
https://bugs.webkit.org/show_bug.cgi?id=235231 Reviewed by Dean Jackson. LayoutTests/imported/w3c: * web-platform-tests/css/selectors/has-argument-with-explicit-scope.tentative-expected.txt: * web-platform-tests/css/selectors/has-basic-expected.txt: * web-platform-tests/css/selectors/parsing/parse-has-expected.txt: Source/WebCore: Nested case ':has(:has(foo))' adds no meaningful capability and would complicate invalidation. See w3c/csswg-drafts#6952 for more details. * css/parser/CSSSelectorParser.cpp: (WebCore::CSSSelectorParser::consumePseudo): Also set m_resistDefaultNamespace like other logical combination pseudo-classes. * css/parser/CSSSelectorParser.h: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288111 268f45cc-cd09-0410-ab3c-d52691b4dbfc
The nested case I think the nested case should be disallowed by the spec. No one seems to have came up with any real uses for that. |
[:has() pseudo-class] Disallow nested :has() https://bugs.webkit.org/show_bug.cgi?id=235231 Reviewed by Dean Jackson. LayoutTests/imported/w3c: * web-platform-tests/css/selectors/has-argument-with-explicit-scope.tentative-expected.txt: * web-platform-tests/css/selectors/has-basic-expected.txt: * web-platform-tests/css/selectors/parsing/parse-has-expected.txt: Source/WebCore: Nested case ':has(:has(foo))' adds no meaningful capability and would complicate invalidation. See w3c/csswg-drafts#6952 for more details. * css/parser/CSSSelectorParser.cpp: (WebCore::CSSSelectorParser::consumePseudo): Also set m_resistDefaultNamespace like other logical combination pseudo-classes. * css/parser/CSSSelectorParser.h: Canonical link: https://commits.webkit.org/246125@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@288111 268f45cc-cd09-0410-ab3c-d52691b4dbfc Canonical link: https://commits.webkit.org/245886.30@safari-613-branch git-svn-id: https://svn.webkit.org/repository/webkit/branches/safari-613-branch@288512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
[:has() pseudo-class] Disallow nested :has() https://bugs.webkit.org/show_bug.cgi?id=235231 Reviewed by Dean Jackson. LayoutTests/imported/w3c: * web-platform-tests/css/selectors/has-argument-with-explicit-scope.tentative-expected.txt: * web-platform-tests/css/selectors/has-basic-expected.txt: * web-platform-tests/css/selectors/parsing/parse-has-expected.txt: Source/WebCore: Nested case ':has(:has(foo))' adds no meaningful capability and would complicate invalidation. See w3c/csswg-drafts#6952 for more details. * css/parser/CSSSelectorParser.cpp: (WebCore::CSSSelectorParser::consumePseudo): Also set m_resistDefaultNamespace like other logical combination pseudo-classes. * css/parser/CSSSelectorParser.h: Canonical link: https://commits.webkit.org/246125@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@288111 268f45cc-cd09-0410-ab3c-d52691b4dbfc Canonical link: https://commits.webkit.org/245886.30@safari-613-branch git-svn-id: https://svn.webkit.org/repository/webkit/branches/safari-613-branch@288512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
I'm fine with disallowing nesting. We've done similar in other non-selector cases to limit complexity. There are definitely use-cases for it, but they're indeed minimal. If at all possible I'd like to avoid disallowing the other selectors, even if the perf isn't ideal. We have much better tools these days to expose and analyze selector performance than we did a decade ago. I presume this means that nested :has() is disallowed even when "shielded" by another selector, like |
Since |
Correct. Any nesting, direct or indirect, is disallowed. |
Can it be clarified if the outer or inner a:has(b, :has(> b)) c {
color: red
} Is the entire selector invalid in this case or only If only the inner is invalid, this selector would essentially become : a:has(b) c {
color: red
} |
I'd render the entire selector invalid. |
I think that would be most clear for stylesheet authors. |
|
It's forgiving for the selectors inside of it, yeah, but the invalidity here is the outer :has(), since it contains a nested :has(). But I could be convinced otherwise, I suppose. |
Not sure how much look ahead is needed and allowed, but that could be a factor? |
It is simpler to just make :has() invalid inside :has() and then follow the usual error handling rules, both in terms of logic and code. |
The CSS Working Group just discussed
The full IRC log of that discussion<fantasai> Topic: [selectors-4] Consider disallowing logical combination pseudo-classes inside :has()<fantasai> github: https://github.com/w3c/csswg-drafts/issues/6952https://github.com//issues/6952 <fantasai> futhark: I think there is agreement to allow combinations like :is() and :where() <fantasai> futhark: But implementors want to disallow :has() inside :has() <fantasai> bkardell_: I think that's my impression as well. I think Safari implements this way as well <fantasai> futhark: Implement in chrome and safari, but buggy <fantasai> futhark: Don't think need to change the spec at this point <fantasai> futhark: or to add any limitations, other than :has() <fantasai> TabAtkins: I support this <TabAtkins> github: <TabAtkins> github: https://github.com//issues/6952 <fantasai> fantasai: proposed then that :has() cannot be nested inside :has() <jensimmons> I've already found a useful usecase for figure:not(:has(:not(img))) { ... } <fantasai> oriol: I think other combinations seem useful, but :has() inside :has() doesn't seem that useful <fantasai> bkardell_: Originally wanted to disallow all of them, but based on feedback went back and made them work <fantasai> bkardell_: said some perf implications, but seem livable-with <fantasai> bkardell_: so let's just prohibit :has() inside :has() <fantasai> astearns: Other opinions? <fantasai> RESOLVED: Disallow nesting :has() inside :has() <TabAtkins> I mean, I'm sure there are use-cases for nested :has(), but they're not as obvious and clearly worth the complexity cost, so I'm happy with this. |
document.querySelector(":has(:has(body))");
// vs.
document.querySelector(":has(:has(body), body)"); In Safari (15.5) the first query throws with The second query returns I am unsure which behaviour is correct, but I suspect this is a bug in Webkit if I compare with the behaviour of WPT also still lacks tests for error recovery in |
Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df
Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3697654 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1013385}
Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3697654 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1013385}
Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3697654 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1013385}
…2 : disallow nesting :has(), a=testonly Automatic update from web-platform-tests Apply the resolution of csswg issue #6952 : disallow nesting :has() Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3697654 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1013385} -- wpt-commits: 74410eadebedbb07ed1ce8031243ac2f7493bf19 wpt-pr: 34385
…2 : disallow nesting :has(), a=testonly Automatic update from web-platform-tests Apply the resolution of csswg issue #6952 : disallow nesting :has() Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3697654 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1013385} -- wpt-commits: 74410eadebedbb07ed1ce8031243ac2f7493bf19 wpt-pr: 34385
Yes, that's a bug in Safari. The tests I just merged from you cover that case, tho. ^_^ |
Remove nesting :has() cases from the existing wpt tests and add a tentative wpt test to check disallowing nesting :has() inside :has(). w3c/csswg-drafts#6952 (comment) Bug: 669058, 1334631 Change-Id: I549ee9d5b1ca17d22f7f8982d0e9ff96df6937df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3697654 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1013385} NOKEYCHECK=True GitOrigin-RevId: e4a649a2f73af3e9d9445e6b27522ba18572d740
I wonder if scoping and nesting can emulate nested Or is it impossible? |
That is disallow nested
:has()
and
These cases complicate style invalidation in the engine too much while also being difficult to reason about and generally not very useful.
It is also easy to make mistakes with
:has(:not(foo))
since it may be non-obvious it is not the same as:not(:has(foo))
.The text was updated successfully, but these errors were encountered: