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)
For numerous reasons, I would really like to have has-child and has-descendant selectors in CSS. These selectors would select an element which has an immediate child matching a selector or a descendant matching a selector, respectively. To avoid conflicting with any official CSS feature, this should most likely use CSS extension syntax, which would make the selectors -moz-has-child and -moz-has-descendant. These selectors would allow rules such as: /* Put a red border around forms that have a field with class="error". */ fieldset:-moz-has-child(.error) { border: 1px solid red; } /* Show a message asking the user to mark at least one checkbox from the form. */ form.choices:-moz-has-descendant(*:checked) div.warning { display: none; } /* Highlight the section containing the current anchor. */ div:-moz-has-descendant(*:target) { background-color: yellow; } /* Put a page break before tables which have at least 20 rows, putting them at the top of their own page. */ table:-moz-has-child(tr:nth-of-type(20)) { page-break-before: always; } /* Put a border between sections, treating divs as sections if they contain an h2 as their first child. */ div:-moz-has-child(h2:first-child) { border-bottom: 1px solid black; } /* Picture the following as an Adblock Plus rule; it could easily replace many of the heuristics currently used to block the containing elements of ads, such as matching divs with a given width or style. */ div:-moz-has-child(img[href^="http://adserver.example.org"]) { display: none; } I think these examples show some of the promise of these selectors.
These proposals look more like the :matches() and :has() proposals than the :subject proposal that was in early drafts of css3-selectors. That said, they're all extremely inefficient to implement. The danger of implementing them is that authors might use them, and then either authors or users will complain about how (unavoidably) slow they are.
Existing proposals: http://www.w3.org/TR/2000/WD-css3-selectors-20001005/#subject-pseudo http://lists.w3.org/Archives/Public/www-style/2002May/0037.html There may be a duplicate bug as well.
Reporter | ||
Comment 3•17 years ago
|
||
Looking at that proposal, I like :subject much better than the approach I've suggested. :subject avoids introducing new syntax which lacks symmetry with the existing selectors. All but one of the examples I gave seems to work with the :subject selector: /* Put a red border around forms that have a field with class="error". */ fieldset:subject > .error { border: 1px solid red; } /* Highlight the section containing the current anchor. */ div:subject *:target { background-color: yellow; } /* Put a page break before tables which have at least 20 rows, putting them at the top of their own page. */ table:subject tr:nth-of-type(20) { page-break-before: always; } /* Put a border between sections, treating divs as sections if they contain an h2 as their first child. */ div:subject h2:first-child { border-bottom: 1px solid black; } /* Picture the following as an Adblock Plus rule; it could easily replace many of the heuristics currently used to block the containing elements of ads, such as matching divs with a given width or style. */ div:subject img[href^="http://adserver.example.org"] { display: none; } The one example that doesn't work: /* Show a message asking the user to mark at least one checkbox from the form. */ form.choices:-moz-has-descendant(*:checked) div.warning { display: none; } That one requires applying subject and then applying further CSS combinators starting from the element chosen by :subject: (form.choices:subject *:checked) div.warning While useful, I can definitely live without that, and it might prove inefficient as well as complex to implement. However, the :subject selector itself does not seem fundamentally less efficient than other CSS selectors or combinators. It does seem harder to implement, but not computationally harder. The main difficulty seems more likely to come from the need to process child elements before rendering the parent. However, in terms of computation, what if Gecko simply matched the CSS rule precisely as it would without :subject, and then *once it found a matching element* it went up to the :subject element and applied the style? That seems no less efficient than existing CSS rules.
It is computationally harder. Just matching as though :subject weren't there is far from trivial (if possible at all), for a number of reasons: * "div:subject p" can match many divs for a single p * "div:subject :link:hover" mean we need to recompute style for the entire document when somebody changes whether they're hovering over a link. That said, by caching a bunch of things in various places and being very careful about what caches to invalidate when, it might be possible.
Er, what I meant is that any reasonably simple way of implementing it is computationally harder. However, there might be some tricks we could use to avoid that, but they're far from trivial, if possible at all.
Actually, if we cache on each node (or maybe even on the style context -- that might be a little trickier) the list of nodes matching rules that would normally have it as a subject but instead had a :subject, it probably wouldn't be that bad, although processing the reresolution process would be tricky. We'd need to build lists of what needed rules changed outside the tree we're reresolving style on -- and then we'd need something like ReParentStyleContext to do a bunch of rebuilding. Except to make this efficient we'd probably want to do something like cache an mNextRuleNode on style contexts -- along with caching both old and new lists of the external rules. Or something roughly like that.
Caching on the style context would be tricky because of the FindChildWithRules optimization.
The other things that would be bad are: * potentially messy re-resolution as we matched rules on descendants (for style contexts that we'd already resolved) * having to do style resolution inside display:none subtrees just to match things whose :subject is outside the subtree
Comment 9•13 years ago
|
||
see http://www.w3.org/TR/selectors4/#subject
Comment 10•10 years ago
|
||
The current editors draft proposes :has().
Updated•9 years ago
|
Comment 11•6 years ago
|
||
How much priority should this have? It's been years and still no priority.... To be honest I really wanted to start using this on my websites....
Comment 12•6 years ago
|
||
Just so you know: If you use jQuery then you can already use it.
Comment 13•6 years ago
|
||
I think you got it wrong. This is for CSS. jQuery is a javascript library, m8... If it was about finding such stuff with javascript, I would have already solved it quite long ago. Currently, I have a javascript hack to do the job which is not fast enough for our objectives.
Comment 14•6 years ago
|
||
(In reply to brunoais from comment #13) > I think you got it wrong. This is for CSS. jQuery is a javascript library, > m8... > If it was about finding such stuff with javascript, I would have already > solved it quite long ago. Currently, I have a javascript hack to do the job > which is not fast enough for our objectives. :has would only be available on the static profile (that is, querySelector), so it wouldn't help you anyway? It'd be way to slow to allow its use in stylesheets.
Comment 15•6 years ago
|
||
If I understood right, the ":has()" has the same meaning as the proposed "$", "^" or "!" selector. Why do you believe it is a slow selector? The node being selected will be in the nodes found stack when running the processing. If I have: <div class="a"> <div class="b1"> <div class="c1"> <div class="d1">Must not find b container of me</div> </div> </div> <div class="b2"> <div class="c2"> <div class="d2 findMe">Find b countainer of me</div> </div> </div> </div> Example 1: a *:has(.findMe) -> Finds all that match ".findMe" (indexed class search) Go up the tree.... Pass through (in order): - .c2 (push .c2 node as possible apply style) - .b2 (push .b2 node as possible apply style) - a (Found a) Add to the cascade table: apply style to c2 and b2 Example 2: :has(.findMe) -> Finds all that match ".findMe" (indexed class search) Go up the tree.... Pass through (in order): - .c2 (push .c2 node as possible apply style) Add to the cascade table: apply style to c2 Example 2: a:has(.d1) -> Finds all that match ".d1" (indexed class search) Go up the tree.... Pass through (in order): - .c1 abort I know these are cases where only one node is found by rightmost selector but the basic idea is the exact same Regardless, :emilio do explain why is :has() is so slow so not to implement on a stylesheet? The above comments approach towards a possible solution before stylo. Now, with stylo, the performance results can be quite different
Comment 16•6 years ago
|
||
Cherry-picking most trivial cases to prove the point? Nice try. First of all you have no way to decide if you should go up or down the tree to be "faster" and either of will be slow in most cases really. Let's take a:has(.d1). Imagine there are 10000 .d1 nodes and one a. And now imagine there are 1 .d1 and 10000 a. And additionally there might be really deep tree. And then you can have div:has(a) and now what you do? As for :has selector, currently you can use XPath (better and faster than implementing :has by hand in JS) where you can make query explicitly specifying if you want to go up or down the tree, and have other constrains that reduce search space. Bottom line is if you really need the :has selector you might want to change your design.
Comment 17•6 years ago
|
||
You're making assumptions about how a browser does style computation that are not true in any browser. The way browser compute the style for an element is checking whether the same element matches all the selectors in the site, not the other way around (as you're suggesting, given a selector, finding all the elements that match, and stashing the result in some kind of global table). That is, selector-matching works looking up and to the left of the tree following combinators. To implement :has you need to potentially look at all the descendants of an element, which is something that no other selector requires you to do. Additionally, supporting :has in stylesheets would have another deep implication, which is that a change in an element could now affect the style of its ancestors, which is just something that doesn't happen with other selectors, and that engines rely on to handle dynamic changes efficiently.
Reporter | ||
Comment 18•6 years ago
|
||
> If I understood right, the ":has()" has the same meaning as the proposed "$", "^" or "!" selector.
I haven't seen those, and I don't know the right search terms to find them. Would you mind pointing to a reference for them?
Comment 19•6 years ago
|
||
:kasper93 : Oh, you mean: Situation 1: A web page with 10000 .d1 nodes and a single a node. In that case, the difficulty of: "a:has(.d1)" is the same as "a .d1". "a .d1" already exists as valid so I don't see anything wrong there. Situation 2: A web page with a single .d1 node and 1000 a nodes. In that case, the difficulty of: "a:has(.d1)" is, indeed, more complex than "a .d1". That is because the algorithm always has to run until the ":root" tag to find all matches. If the node with class "d1" is not inside any of the <a> tags, then the computation required is the same as there was no ":has()". Otherwise, it relies on how deep the single tag of class "d1" is. In a realistic situation, though, a tag is not placed 1000 tags deep. In the most complex websites, the closest ":root" or ":scope" tag is no more than 50 tags deep. In such realistic situation, only, at most, 47 tags would be the a tags referred there. The rest to the 1000 a tags would be ignored while processing that selector because they would not be in the upwards search graph. As for: "div:has(a)"... What's the issue with that one? It is true it is more efficient to have "div:has(> a)" but it is still the same kind of thing. I don't get the problem with that :emilio > The way browser compute the style for an element is checking whether the same element matches all the selectors in the site, not the other way around (as you're suggesting, given a selector, finding all the elements that match, and stashing the result in some kind of global table). OK > That is, selector-matching works looking up and to the left of the tree following combinators. To implement :has you need to potentially look at all the descendants of an element, which is something that no other selector requires you to do. True from a conceptual standpoint but it doesn't have to be implemented that way. > Additionally, supporting :has in stylesheets would have another deep implication, which is that a change in an element could now affect the style of its ancestors, which is just something that doesn't happen with other selectors, and that engines rely on to handle dynamic changes efficiently. OK. That is a good point. > I haven't seen those, and I don't know the right search terms to find them. Would you mind pointing to a reference for them? It's not easy to find... Still... I found a commit of when the idea of w3c at the time was to use "!" https://github.com/w3c/csswg-drafts/blob/3e071f642fa737adce2a7c8529606049f29fdaff/selectors/Overview.html#L1245 The "$" was very very short lived... after 20 minutes looking for it in the drafts, I couldn't find it. The "^" I don't remember but I did find it being mentioned in an article from that time. See: https://hugogiraudel.com/2014/02/13/parent-selector/ There are mentions about "!" in one of the comments of: https://css-tricks.com/parent-selectors-in-css/ back when it was very young. I think that's about it of what I can find. There were not many news at the time too.
Updated•6 years ago
|
Comment 20•6 years ago
|
||
(In reply to David Baron :dbaron: 🏴 ⌚UTC-7 from comment #1) > ... > ... > ... extremely inefficient to implement. ... > ... will complain about how (unavoidably) slow they are. Can't the algorthim just break up at a certain point, when the nesting/recursion (or whatever makes it inefficient) gets too deep/high and leave a warning in the console?
Comment 22•6 years ago
|
||
I actually thought this would be a rule that can be almost directly solved... For "a:has(b.show)", for example, it would just be the same work as matching "a b.show" except it is "a" tag that gets the rules applied instead of "b" tag.....
(In reply to altugtekin85 from comment #20) > Can't the algorthim just break up at a certain point, when the > nesting/recursion (or whatever makes it inefficient) gets too deep/high and > leave a warning in the console? A warning in the console and a broken web page? I don't think such an approach could work unless the limits were specified, but it's not clear what it is you're proposing to limit, or how that would interfere with the use cases for the feature. (I could try to work that out... but it seems like a decent amount of work that isn't an appropriate use of "needinfo?".)
Comment 24•6 years ago
|
||
In your first comment you state that: (In reply to David Baron :dbaron: 🏴 ⌚UTC-7 from comment #1) > ... they're all extremely inefficient to implement. The danger of implementing > them is that authors might use them, and then either authors or users will > complain about how (unavoidably) slow they are. Given that statement I concluded, that when the browser is evaluating the CSS containing the "has()" it somehow enters an inefficient loop, which has an exponential (or n^99) runtime. And my thought was that, if I knew the source code better and had the time to edit it, I would simply count the number of iterations the browser spends in the loop and eventually at a fixed value break out of the loop, so that nobody complains about bad performance, but on the other hand leaves a warning, thsat the developer must change his/her CSS in order to make it work again. (In reply to David Baron :dbaron: 🏴 ⌚UTC-7 from comment #23) > (In reply to altugtekin85 from comment #20) > > Can't the algorthim just break up at a certain point, when the > > nesting/recursion (or whatever makes it inefficient) gets too deep/high and > > leave a warning in the console? > > ... but it's not clear what it is you're proposing to limit ... Was the above explanation elaborate enough?
Comment 25•6 years ago
|
||
A reference: This feature is implemented first(?) in Prince 12 https://www.princexml.com/. See the documentation here: https://www.princexml.com/doc-refs/ [search ":has("]. I use it to generate PDF from XML or HTML. I would like to use this feature in Firefox to preview a _static_ (CSS formatted) XML document. Is this case part of "snapshot profile" described in CSS 4 Selector Specification here: https://drafts.csswg.org/selectors/#snapshot-profile?
Comment 26•3 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•2 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•2 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•2 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•2 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•2 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•2 years ago
|
||
Patches welcome, fwiw. I'm not likely to get to this super-soon (but it's in the roadmap)
Comment 39•2 years ago
|
||
Emilio, can we please see your roadmap? :)
Comment 40•2 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•2 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•2 years ago
|
||
The Chromium people enabled their implementation by default a few days ago.
Sebastian
Comment 44•2 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
Updated•2 years ago
|
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.
Updated•2 years ago
|
Comment hidden (advocacy) |
Comment hidden (metoo) |
Comment 67•1 year 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•1 year 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•1 year 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.
Updated•1 year ago
|
Comment 72•1 year 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•1 year ago
|
||
There's a fair amount of ongoing work in dependent bugs, please follow those for progress.
Comment 74•1 year 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
Comment hidden (metoo) |
Comment hidden (metoo) |
Comment 77•1 year 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
Updated•11 months ago
|
Comment 78•11 months 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•11 months ago
|
||
Yup! This was recently enabled by default on Nightly (only Nightly for now), in bug 1853701.
Updated•10 months ago
|
Comment 80•9 months 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•9 months ago
|
||
Any idea about when this could land on stable?
Firefox 121 (see bug 1858743).
Comment 82•8 months 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•8 months 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•8 months 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•8 months 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•8 months ago
|
||
Filed as bug 1869771
Comment hidden (advocacy) |
Comment 88•8 months 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•8 months 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•8 months ago
|
Description
•