Bug 234556 - [:has() pseudo-class] Support for style invalidation with missing interactive pseudo-classes
Summary: [:has() pseudo-class] Support for style invalidation with missing interactive...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: Safari Technology Preview
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL: https://codepen.io/leaverou/pen/KKXvq...
Keywords: InRadar
Depends on: 238900 240345 240762 234561 234636 234815 238451 238894 238899 238902 238923 238994 240329 249455 249456 262836
Blocks: 227702
  Show dependency treegraph
 
Reported: 2021-12-21 03:18 PST by Lea Verou
Modified: 2023-10-21 14:31 PDT (History)
6 users (show)

See Also:


Attachments
screenshot of has pseudo class bug (227.10 KB, image/jpeg)
2021-12-28 07:45 PST, Brandon McConnell
no flags Details
screenshot of has pseudo class bug #2 (205.36 KB, image/png)
2021-12-28 08:04 PST, Brandon McConnell
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Lea Verou 2021-12-21 03:18:44 PST
:has() does not seem to match when the argument is an interactive pseudo-class (:focus, :checked, :target). 
I’m not sure it's an invalidation issue, because it doesn't apply even when the pseudo-class applies on startup (e.g. a pre-checked checkbox).

Testcase: https://codepen.io/leaverou/pen/KKXvqjG?editors=1100

(Huge thanks to everyone who made :has() happen — what an exciting time!)
Comment 1 Antti Koivisto 2021-12-21 03:43:27 PST
Thanks for the report.

Of these :focus should be working at least in basic cases. Changing 

.has.focus:has(:checked)

to

.has.focus:has(:focus)

makes that subtest work as expected.

The others are broken though.
Comment 2 Lea Verou 2021-12-21 03:46:28 PST
Oops! Fixed the testcase, thanks!
Comment 3 Lea Verou 2021-12-21 03:57:22 PST
Also updated the tests to include :valid, which behaves very oddly:

:has(:valid) seems to match *regardless* of whether a valid control is actually contained within, and said matching doesn't change as descendant controls go from valid to invalid and vice versa.
Comment 4 Radar WebKit Bug Importer 2021-12-21 04:13:32 PST
<rdar://problem/86763225>
Comment 5 Antti Koivisto 2021-12-21 04:22:23 PST
Basically we need to use Style::PseudoClassChangeInvalidation around pseudo-class changes for them to invalidate correctly within :has().
Comment 6 Bill Criswell 2021-12-21 17:48:00 PST
I observed some interesting behavior too. This Sandbox helps explain the situation: https://codesandbox.io/s/silly-gagarin-y0cub
Comment 7 Antti Koivisto 2021-12-23 04:25:11 PST
(In reply to Bill Criswell from comment #6)
> I observed some interesting behavior too. This Sandbox helps explain the
> situation: https://codesandbox.io/s/silly-gagarin-y0cub

That seems to work fine now after the latest fixes.
Comment 8 Brandon McConnell 2021-12-28 07:45:53 PST
Created attachment 448043 [details]
screenshot of has pseudo class bug
Comment 9 Brandon McConnell 2021-12-28 07:46:47 PST
One unexpected side effect I'm seeing so far— it appears that :has sometimes matches for unmatching elements. The inspector doesn't show the styles but they appear on-page.

Example URL: https://codepen.io/brandonmcconnell/pen/45b67ffa16dc41614efdd140bef1f439

Example screenshot attached
Comment 10 Brandon McConnell 2021-12-28 08:00:06 PST
I have altered my example URL that I linked above to expand on the side effect I noticed. It appears that all three div's, even those that should not be matching are receiving the "has" styles for their own background-color, however, only the correct one receives styles once an additional pseudo-element is specified after the :has pseudo-selector.
Comment 11 Brandon McConnell 2021-12-28 08:04:42 PST
Created attachment 448044 [details]
screenshot of has pseudo class bug #2

This new screenshot demonstrates the bug, where the "has" styles are visually inherited by elements that do not match the selector, but not their pseudo elements.
Comment 12 Brandon McConnell 2021-12-28 08:18:44 PST
Upon further investigation, this bug appears to occur during rendering, and if I comment the styles using the inspector and then un-comment then, the styles auto-correct themselves.

I have recorded a Loom video demonstrating this: https://www.loom.com/share/0cf9c18a99a8421f9957ff04c34f64de

This bug is critical to the use of :has() so this should be resolved before the :has() pseudo-class is released into the production browser.
Comment 13 Lea Verou 2021-12-28 10:18:10 PST
Brandon, could you please file a new bug so its status can be tracked separately?
Comment 14 Brandon McConnell 2021-12-28 14:25:30 PST
Bill / Lea / Antti — I will open a separate ticket for the concerns I raised.
Comment 15 Brandon McConnell 2021-12-28 14:43:50 PST
I opened two new tickets to account for the bugs I found:

Bug 234732 - [:has() pseudo-class] Styles matching non-matching elements on load
https://bugs.webkit.org/show_bug.cgi?id=234732

Bug 234733 - [:has() pseudo-class] Not matching elements it should
https://bugs.webkit.org/show_bug.cgi?id=234733