:is containing :has/:nth-child(of) may not invalidate correctly
Categories
(Core :: CSS Parsing and Computation, defect)
Tracking
()
People
(Reporter: i3vg6j1f, Assigned: dshin)
References
(Blocks 1 open bug)
Details
Attachments
(4 files)
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0
Steps to reproduce:
- Apply some styles under this selector:
:is([data-pressed=true], :has(.stuff)). - Use JS to toggle
data-pressed.
See playground (press button): https://developer.mozilla.org/en-US/play?id=Q82Vp%2FpR%2Bzyvu9fwfTudUzpPjXseTppN65OFbz7Wh0C1YjAlMH86s4FVMPcf0%2BaqgpMz4d5UBodeRz8n
Actual results:
Selector is matched correctly on initial load, but not for future updates.
If :has(.stuff) is removed from the selector list, then it works correctly.
(Also works correctly in Blink and Webkit)
Expected results:
Selector should continue to match the correct state for both initial loads and future updates.
Side note: I'm not sure if there are performance concerns with using :has inside :is. If that is the case, it would be nice if devtools showed a 🐢warning, similar to how it does for unconstrained selectors like :has(*).
Updated•2 years ago
|
Comment 2•2 years ago
|
||
dshin, mind taking a look?
I do see a behavior difference between Firefox vs. WebKit/Chrome here; in the linked MDN playground, we keep the hotpink outline after the button is pressed whereas it disappears when "off" is showing (e.g. after 1 press) in WebKit/Chrome.
| Assignee | ||
Comment 3•2 years ago
•
|
||
Oh... Ouch.
We always return true for :has() in invalidation context because we're just marking for invalidation and we'll match later while styling.
So in this case we have :is(non-has-selector, has-selector), where non-has-selector initially matches, but then no longer does. Our invalidator examines now vs then matches for the element, only marking for invalidation if it changed. For the "then" match, non-has-selector matches, and for the "now" match, has-selector matches, so we don't end up marking the element for invalidation.
:nth-child(N of selector) has the same issue.
| Assignee | ||
Updated•2 years ago
|
| Assignee | ||
Comment 4•2 years ago
|
||
STR: Load the test case, wait 1 second
Expected: Purple square should disappear
Actual: Purple square does not disappear (Unless you force restyle by e.g. opening the inspector)
| Assignee | ||
Comment 5•2 years ago
|
||
Updated•2 years ago
|
| Assignee | ||
Updated•2 years ago
|
Comment 6•2 years ago
|
||
I was able to reproduce this issue with the test case from comment 4 on MacOS 13.2.1 using Fx 121.0.1, 122.0b9 and Nightly 123.0a1(2024-01-14). I noticed that the issue is not reproducible on Fx 120.0.1.
| Assignee | ||
Comment 7•1 year ago
|
||
(Sorry - late reply) Ah, :has shipped on release 121.
| Assignee | ||
Comment 8•1 year ago
|
||
| Assignee | ||
Comment 9•1 year ago
|
||
Depends on D205256
Comment 10•1 year ago
|
||
Comment 12•1 year ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/3b319cf7f343
https://hg.mozilla.org/mozilla-central/rev/068df8e3c3c6
Updated•1 year ago
|
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
Description
•