Skip to content

[selectors-4] Consider disallowing :host, :host(), :host-context() inside :has() #7212

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

Closed
byung-woo opened this issue Apr 12, 2022 · 1 comment
Labels
selectors-4 Current Work

Comments

@byung-woo
Copy link
Member

The only meaningful usage of :host inside :has() is using it with :scope.

  • .b:has(:host .a :scope .c) { color: green }

In the above example, the :scope inside the :has() matches the subject element of the style rule according to the current relative selector absolutizing spec

But as pointed in some other issues (issue 6399, issue 7211), the above expression has the same problem in the below expression. (increasing invalidation complexity)

  • .b:has(:is(:host .a :scope) .c) { color: green }

So, it would be better to use below expression instead of the above.

  • :host .a .b:has(.c) { color: green }

How about disallowing :host, :host(), :host-context() inside :has() to avoid increasing complexity?

@byung-woo byung-woo changed the title Consider disallowing :host, :host(), :host-context() inside :has() [selector-4] Consider disallowing :host, :host(), :host-context() inside :has() Apr 13, 2022
@byung-woo byung-woo changed the title [selector-4] Consider disallowing :host, :host(), :host-context() inside :has() [selectors-4] Consider disallowing :host, :host(), :host-context() inside :has() Apr 13, 2022
@jensimmons jensimmons added the selectors-4 Current Work label Apr 21, 2022
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [selectors-4] Consider disallowing :host, :host(), :host-context() inside :has(), and agreed to the following:

  • RESOLVED: No change
The full IRC log of that discussion topic: [selectors-4] Consider disallowing :host, :host(), :host-context() inside :has()
github: https://github.com//issues/7212
futhark: Given resolution wrt :scope, at least from Chrome side, we agree that :host-context will neve match inside :has() because it needs to have sibling/parent ... shadow tree
q+
futhark: not a perf problem, but it will never match
futhark: proposed resolution from our side is no change
TabAtkins: :host will never match as final selector, but the example here ...
.b:has(:host .a .c)
TabAtkins: slightly simplified version of a selector in the issue
TabAtkins: this would still match
TabAtkins: however it's exactly equivalent to just moving the :host outside
TabAtkins: if we were to ban it, wouldn't hurt anything, but is matchable in this instance
bkardell_: Because doesn't begin with a relative combinator
TabAtkins: so evaluates globally against the context
q-
bkardell_: This is where the whole weird context comes from
bkardell_: I think a lot of ppl would not expect that to match
futhark: From impl side of things, it's not an important issue
futhark: removing special meaning of :scope means it's not a perf issue
bkardell_: so you would ... walk all the way up the tree?
bkardell_: Seems weird to me that this should match
bkardell_: basically nobody would expect it
TabAtkins: it's the same as putting :root in there
TabAtkins: why expect not to match?
bkardell_: Even in jquery etc., :has() you start matching at the boundary, you don't walk all the way up the tree
q+
TabAtkins: Am I misremembering this?
:has(:is(:host .a)
)
maybe you mean something like that?
q-
fantasai: The host element doesn't necessarily ahve to be inside...
fantasai: the host doen't have to be in the :has()
fantasai: When you have :is() tho, that doesn't necessarily get scoped.
fantasai: So if you nest it like this, this could match.
:has(:is(:root .a)) would match, for example
TabAtkins: That's right, would do it
fantasai: My inclination is to make this invalid, would be easier for everyone to understand and get it right
astearns: You would get the same effect by moving :host outside of :has()
TabAtkins: yes
q?
q+
the bot is dead?
A:has(:is(:host B)) rewrites to :is(:host A, A:host):has(B)
bkardell_: Previous example was one that Oriol pointed out. did we agree to the opposite, that you can't use :is()? or did I misunderstand?
TabAtkins: all other relational selectors are fine
bkardell_: what was proposal?
TabAtkins: make :host illegal inside of :has() context
emilio: If no reason to disallow performance-wise, probably more work to disallow. But don't mind either way
futhark: I don't have strong feelings either way
astearns: given confusion we just put ourselves through, I have a slight preference for disalowing
astearns: because it's an unreadable way of expressing this
bkardell_: I agree
TabAtkins: :host does have theoretical use in here, because if you want to select a top-level element in your shadow tree need to use ':host > element'
TabAtkins: it's no more confusing than :root in this context
TabAtkins: so that part doesn't bother me
emilio: Why would you want to use direct child combinator? You can't have anything that's direct child of host in here
bkardell_: ...
emilio: so :host :has(stuff)
emilio: You would need to be :host(:has())
.foo:has(:is(:host > .top-level .bar))
TabAtkins: This is a meaningful selector
TabAtkins: it's a .foo that has a non-top-level-.bar inside it
emilio: yeah, ok, fine
emilio: Assuming there's no reason to ban it perf-wise, then seems fine to keep it
astearns: I'm hearing a lot of "eh"
+1
TabAtkins: I suggest we leave as-is, unless on further investigation it has a perf implication
futhark: I agree
RESOLVED: No change
s/change/change; :host etc. continues to be allowed inside :has()/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selectors-4 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants