: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•11 months ago
|
Comment 2•11 months 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•11 months 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•11 months ago
|
Assignee | ||
Comment 4•11 months 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•11 months ago
|
||
Updated•11 months ago
|
Assignee | ||
Updated•11 months ago
|
Comment 6•10 months 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•9 months ago
|
||
(Sorry - late reply) Ah, :has shipped on release 121.
Assignee | ||
Comment 8•8 months ago
|
||
Assignee | ||
Comment 9•8 months ago
|
||
Depends on D205256
Comment 10•8 months ago
|
||
Comment 12•8 months ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/3b319cf7f343
https://hg.mozilla.org/mozilla-central/rev/068df8e3c3c6
Updated•8 months ago
|
Updated•7 months ago
|
Description
•