Implement the :has() pseudo class
Categories
(Core :: CSS Parsing and Computation, enhancement)
Tracking
()
People
(Reporter: josh, Unassigned)
References
(Depends on 3 open bugs, Blocks 4 open bugs, )
Details
(Keywords: dev-doc-needed, parity-chrome, parity-safari)
Reporter | ||
Comment 3•17 years ago
|
||
Comment 9•13 years ago
|
||
![]() |
||
Comment 10•10 years ago
|
||
Updated•10 years ago
|
Comment 11•7 years ago
|
||
Comment 12•7 years ago
|
||
Comment 13•7 years ago
|
||
Comment 14•7 years ago
|
||
Comment 15•7 years ago
|
||
Comment 16•7 years ago
|
||
Comment 17•7 years ago
|
||
Reporter | ||
Comment 18•7 years ago
|
||
Comment 19•7 years ago
|
||
Updated•7 years ago
|
Comment 20•7 years ago
|
||
Comment 22•7 years ago
|
||
Comment 24•6 years ago
|
||
Comment 25•6 years ago
|
||
Comment 26•4 years ago
|
||
Chrome: Intent to Prototype
https://groups.google.com/a/chromium.org/g/blink-dev/c/hqkcKdDrhXE/m/qzEVzxbfAwAJ
Comment 27•3 years ago
|
||
Please implement it as "exclamation" version .
The div p!+ul>li
is more readable than div+p:has(+ul>li)
. Excalamtion mark to point element to be style applied.
Comment 28•3 years ago
|
||
Safari 15 has experimental for support
![]() |
||
Comment 29•3 years ago
|
||
Safari Technology Preview Release Notes - Release 137
Enabled support for :has() pseudo-class by default
— https://developer.apple.com/safari/technology-preview/release-notes/
Comment 30•3 years ago
•
|
||
It looks like the Chromium team is also actively working on an implementation under https://crbug.com/669058.
Sebastian
Comment 32•3 years ago
|
||
(In reply to Mozira from comment #27)
Please implement it as "exclamation" version .
Thediv p!+ul>li
is more readable thandiv+p:has(+ul>li)
. Excalamtion mark to point element to be style applied.
Ternary-style operators are not more readable; I think most authors would consider it far less readable than an explicit descriptive word. CSS does not use ternary-style operators for anything else, to my knowledge, so it would be a change in form to do so here, and would cause needless confusion, considering not only the CSS specification but also other vendors (Safari and Chrome) use ":has()" already.
Comment 33•3 years ago
|
||
(In reply to Tyler from comment #32)
(In reply to Mozira from comment #27)
Please implement it as "exclamation" version .
Thediv p!+ul>li
is more readable thandiv+p:has(+ul>li)
. Excalamtion mark to point element to be style applied.Ternary-style operators are not more readable; I think most authors would consider it far less readable than an explicit descriptive word. CSS does not use ternary-style operators for anything else, to my knowledge, so it would be a change in form to do so here, and would cause needless confusion, considering not only the CSS specification but also other vendors (Safari and Chrome) use ":has()" already.
It's not a request for a ternary operator. I don't understand why you understood like that but that's not the important part.
The request is to use the !
character as the marker of which element is intended to be obtained, not as a ternary operator. It can be some other character. Can be an @
character even. It's just that that is shorter than a function-like format.
As for me, I don't really mind which way it's actually done as long as the feature is there and it's as usable as eachever.
Comment 34•3 years ago
|
||
(In reply to brunoais from comment #33)
(In reply to Tyler from comment #32)
Please implement it as "exclamation" version .
Thediv p!+ul>li
is more readable thandiv+p:has(+ul>li)
. Excalamtion mark to point element to be style applied.It's not a request for a ternary operator. I don't understand why you understood like that but that's not the important part.
The request is to use the!
character as the marker of which element is intended to be obtained, not as a ternary operator. It can be some other character. Can be an@
character even. It's just that that is shorter than a function-like format.As for me, I don't really mind which way it's actually done as long as the feature is there and it's as usable as eachever.
I am not in support of a shortened syntax. How would you you get further selection outside the has? For example, div+p:has(+ul>li)+p
from div+p!+ul>li+p
? The interpreter would easily see this as being div+p:has(+ul>li+p)
instead which may not be what you were looking to do.
Comment 35•3 years ago
|
||
Please note that this is not the place to discuss the syntax of this feature. The right place would be the GitHub repository of the CSS Working Group.
Having said that, I'm afraid that this ship has already sailed. There were many discussions regarding !
vs. :has()
and other ways to express a parent selector and the Working Group decided on :has()
in the end. Furthermore, as Tyler already mentioned, WebKit already shipped this and people are working on an implementation for Chromium.
So, it's very unlikely that the syntax will be reconsidered at this point.
Sebastian
Comment 36•3 years ago
|
||
This feature needs to be implemented experimentally in Firefox (by making it enableable via about:config).
This will allow:
- to experiment with this feature
- to allow performance testing
- accelerate the chances of adoption
Comment 37•3 years ago
|
||
Patches welcome, fwiw. I'm not likely to get to this super-soon (but it's in the roadmap)
Comment 39•3 years ago
|
||
Emilio, can we please see your roadmap? :)
Comment 40•3 years ago
|
||
Currently that document (which is specific for the Layout / APZ teams) is Mozilla-internal. It doesn't have any secrets, so I can try to ask to make it public. That said, it's subject to change so not sure you could draw a lot of conclusions...
The layout team standup notes are public tho, and probably a better view of what the team is up-to, if that's what interests you :-)
Comment 41•3 years ago
|
||
Chromium has published their "intent to ship": https://groups.google.com/a/chromium.org/g/blink-dev/c/bRsbl3wLuyk/m/mt3iSKNHBQAJ?pli=1
Expected in Chrome 105. It would be great to get Firefox to work on this for cross-browser compatibility
Comment 42•3 years ago
|
||
The Chromium people enabled their implementation by default a few days ago.
Sebastian
Comment 44•3 years ago
•
|
||
Note, there was a CSSWG resolution in last week's working group meeting:
RESOLVED: Disallow all current pseudo-elements inside of :has(), allow future pseudo-elements to define that they are valid if useful/possible.
https://github.com/w3c/csswg-drafts/issues/7463#issuecomment-1196971909
See the examples from the first comment there:
Selectors like
ol:has(li::marker)
andsection:has(p::first-line)
are problematic and we should make all pseudo-elements invalid inside:has()
.
If our current implementation (e.g. via bug 1771896) is already far enough along that we accept such selectors and would need to land another patch to add restrictions to reject them, then it might be worth filing a bug on that; otherwise/alternately we can just consider this as being part of the main/remaining portion of work under this main bug here.
Comment 45•2 years ago
|
||
The following works in Edge but not in Firefox with the flag enabled:
<html>
<meta name="viewport" content="width=device-width">
<style>label:has(input[type="hidden"]) {
display: none;
}
</style>
<label>
a
<input type="hidden" name="a" value="a">
</label>
<label>
b
<input type="text" name="b" value="b">
</label>
</form>
</html>
Comment 46•2 years ago
|
||
(In reply to cyril.walle from comment #45)
The following works in Edge but not in Firefox with the flag enabled:
<html> <meta name="viewport" content="width=device-width"> <style>label:has(input[type="hidden"]) { display: none; } </style> <label> a <input type="hidden" name="a" value="a"> </label> <label> b <input type="text" name="b" value="b"> </label> </form> </html>
Even after fixing the HTML it doesn't work as expected:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>label:has(input[type="hidden"]) {
display: none;
}
</style>
</head>
<body>
<label>
a
<input type="hidden" name="a" value="a">
</label>
<label>
b
<input type="text" name="b" value="b">
</label>
</body>
</html>
Like this, both labels are not displayed.
If you swap the labels, both labels are displayed
The problem seem to be that only the first label is being evaluated (or the only one whose evaluation counts) and then applying the same value to all other labels. This can be a cache issue...
Comment 47•2 years ago
|
||
It's expected that there are bugs, :has()
implementation is experimental, that's why it's not enabled anywhere by default.
.matches
/ .querySelector
are expected to behave correctly. What you're seeing is an interaction with the style sharing cache where we try to detect when we can just share the style of the elements. It's not accounting for :has
, so it wrongly shares the style of the first label with the second.
Updated•2 years ago
|
Comment hidden (advocacy) |
Comment hidden (advocacy) |
Comment 50•2 years ago
|
||
The implementation not the spec is experimental.
Comment 51•2 years ago
|
||
It's expected that there are bugs,
:has()
implementation is experimental, that's why it's not enabled anywhere by default.
And to iterate on that, the implementation in Firefox (Gecko) is experimental. And "not enabled anywhere by default" means not enabled in any Firefox version by default yet.
Sebastian
Comment 52•2 years ago
|
||
Child/sibling combinators inside :has()
are ignored.
The following works in Chroimum, but not in Firefox with the flag enabled.
<style>
div:has(> span){ font-size: 150%; }
div:has(+ div){ color: red; }
div:has(~ div){ border: thin solid black; }
</style>
<div>
<span>a</span>
</div>
<div>
b
</div>
Comment 53•2 years ago
|
||
(In reply to teterumu from comment #52)
Child/sibling combinators inside
:has()
are ignored.
They are not implemented yet. See bug 1774588.
Sebastian
Comment hidden (advocacy) |
Comment hidden (advocacy) |
Comment 56•2 years ago
|
||
Pseudo-classes do not seem to work inside :has()
.
I tried :not
, :checked
, :valid
/:invalid
.
Here is example with :not
<style>
div:has(h1) {
background: red;
}
div:has(:not(h1)) {
background: green;
}
</style>
<div>
<h1>h1</h1>
</div>
<div>
<h2>h2</h2>
</div>
All of them work in Brave browser (Chromium based).
Comment 57•2 years ago
|
||
As mentioned in the previous comments, :has()
isn't fully implemented in Gecko yet, which is why it's still behind the layout.css.has-selector.enabled
preference, which is disabled by default.
You may want to have a look at the bugs linked to in the "Depends on" and "Blocks" list above, especially bug 1771692 and bug 1748399, which relate to pseudo-classes within :has()
.
Sebastian
Comment 59•2 years ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #40)
Currently that document (which is specific for the Layout / APZ teams) is Mozilla-internal. It doesn't have any secrets, so I can try to ask to make it public. That said, it's subject to change so not sure you could draw a lot of conclusions...
The layout team standup notes are public tho, and probably a better view of what the team is up-to, if that's what interests you :-)
Checking the links on the [mozilla wiki](https://wiki.mozilla.org/Platform/Layout the notes linked above seem to be still the most up-to-date document, even though their last entry is from six months ago. Can you tell if a push for getting :has()
ready to be shipped is anywhere on a current roadmap? I had a look at the tickets mentioned by Sebastian above, but they haven't been active for 7/12 months respectively.
Comment 60•2 years ago
|
||
(In reply to Albert Scheiner [:alberts] from comment #59)
their last entry is from six months ago.
This link goes up to last week:
https://docs.google.com/document/d/1BbKGHgmDjD87f6Dt4mMXrZysch5END7AoCIY1cwGSdY/edit
Comment 61•2 years ago
|
||
I recieved a question via Support, any update on when the :has() CSS selector will be supported?, is there any ETA of this?
Thanks
Comment 62•2 years ago
|
||
We plan to work on this in the first half of this year.
Comment hidden (advocacy) |
Comment hidden (metoo) |
Comment 67•2 years ago
|
||
Is there any update on this? @emilio? A timeline?
I have a system I'm hoping to release in the fall that would be best done using :has, but now, even with the config flag set on v.111.01, it's simply not working.
Comment 68•2 years ago
|
||
There's work going in progress on this. It's not expected that it doesn't work with the flag off (specially on release instead of nightly where the latest changes land), that's why it's off by default.
![]() |
||
Comment 69•2 years ago
|
||
Hello. I don't want to add unnecessary bug noise, but I was trying out :has() in a low-critical area to tweak handling of row highlighting. I ran into a couple of bugs that I put in a testcase here:
https://m8y.org/tmp/testcase500.xhtml
Testcase demoing an issue where Firefox Nightly 2023-03-24 with :has() enabled leaves hover highlighting active (move down the rows in column E or F), or does not apply hover highlighting (move up from the bottom into the Y cells).
I was wondering if this was known. I didn't spot it in the linked bugs. Chrome seems to evaluate my CSS as I expected.
Comment 72•2 years ago
|
||
This tweet gained a good deal of traction over the past couple days. @Emilio do you have any update? We're nearing the end of H1 already by now.
Comment 73•2 years ago
|
||
There's a fair amount of ongoing work in dependent bugs, please follow those for progress.
Comment 74•2 years ago
|
||
Just an FYI that (currently widely used) Tailwind CSS will have :has()
classes in its upcoming release:
https://twitter.com/adamwathan/status/1663582608528224257
https://github.com/tailwindlabs/tailwindcss/pull/11318
Updated•2 years ago
|
Comment hidden (metoo) |
Comment hidden (metoo) |
Comment 77•2 years ago
|
||
(In reply to Kenneth Hoff from comment #76)
Where can I go to get news on this feature? Can we expect it before the end of the year?
This bug and the ones blocking it are probably the best place to follow the implementation of :has()
.
As it is actively being worked on and it is part of the Interop 2023 initiative, I assume it will be released this year. Having said that, I'm also just a follower and not an implementer.
Sebastian
Comment 78•1 year ago
|
||
I just tested on Firefox Nightly 120, it looks like it's finally there! Here's the Interop 2023 page referencing the feature: https://wpt.fyi/results/css/selectors/dir-pseudo-in-has.html?label=master&label=experimental&product=chrome&product=firefox&product=safari&aligned&view=subtest&q=label%3Ainterop-2023-pseudos
Comment 79•1 year ago
|
||
Yup! This was recently enabled by default on Nightly (only Nightly for now), in bug 1853701.
Comment 80•1 year ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #79)
Yup! This was recently enabled by default on Nightly (only Nightly for now), in bug 1853701.
Any idea about when this could land on stable? Funny to see Nightly is the first browser at 100% interop compat on the :has() subject though!
Comment 81•1 year ago
|
||
Any idea about when this could land on stable?
Firefox 121 (see bug 1858743).
Comment 82•1 year ago
|
||
This example (last example on page) using a combination of :not and :has to create a dotted border still doesn't seems to work in 121 beta og 122 nightly. Is this a bug or am I missing something?
Comment 83•1 year ago
|
||
Christian Aarfing: the website you pointed to doesn;t have the correct CSS applied to it. Their linked Pen does have the CSS code and it seems to work correctly: https://codepen.io/matuzo/pen/poKxKEN
Comment 84•1 year ago
|
||
(In reply to Jamie Katz from comment #83)
Christian Aarfing: the website you pointed to doesn;t have the correct CSS applied to it. Their linked Pen does have the CSS code and it seems to work correctly: https://codepen.io/matuzo/pen/poKxKEN
Thank you. You're probably right. It threw me that it worked in Safari and Chrome :)
Comment 85•1 year ago
|
||
Actually, I think I'm wrong, sorry! The page does have this CSS:
.democard3.card:not(:has(img))
{
border-style: dotted;
}
But it doesn't get applied on FF (Nightly 2023-12-13) or show up in devtools. In devtools if I add/remove one of the classes from the .democard3 (the one without the img), it does apply the :has CSS and show up.
Funnily, there doesn't seem to be the same problem on the Pen page https://codepen.io/matuzo/pen/poKxKEN
.right:not(:has(img))
{
border-style: dotted;
}
Comment 86•1 year ago
|
||
Filed as bug 1869771
Comment hidden (advocacy) |
Comment 88•1 year ago
|
||
FF121.0.0 - In Inspector's Search HTML
field:
element:has(element)
doesn't work. E.g. body:has(main)
. The suggestion shows body:h
when I close the parenthesis.
It works fine with attribute attribute, class and ID selectors. If work fine with a child or subsequent sibling combinator. No suggestions though.
It doesn't work with the next-child combinator for element names either.
header:has(+main)
doesn't work. (The suggestion shows header:has(+main)r
)
Interestingly enough, neither does header+main
. Even though it does get suggested when typing.
Comment 89•1 year ago
|
||
Thanks, filed that as bug 1871881, but for the next time, please do not use comments to report bugs or enhancements, use the relevant form. Otherwise, it relies on me or someone else noticing the comment, then remembering to file it, and it makes harder to follow-up with the original reporter etc as needed.
I'm going to close this bug, since this is implemented, and file a follow-up bug for tracking :has() - related bugs.
Updated•1 year ago
|
Description
•