)]}'
{"id": 6296574159355904, "name": "User action pseudo class top layer boundary", "summary": "This feature represents the behavior described in this section of the CSS spec:\n\nhttps://www.w3.org/TR/selectors-4/#useraction-pseudos\n\nwhich says that :hover, :active, and :focus-within match on the parents of elements, but only up to the first top layer element in the parent chain. The change for Chromium is that last \"up to the top layer\" part of this behavior.\n\nConcretely, this means that in the following structure if the user hovers the `<button>`, then the `:hover` pseudo class will match the `<button>` and the popover, but will not match the `<main>` element.\n\n```\n<main>\n  <div popover>\n    <button></button>\n  </div>\n</main>\n<script>document.querySelector('[popover]').showPopover();</script>\n```\n\nThe rationale behind this change is that typically top layer elements are rendered \"elsewhere\", in a location that is disconnected from the parent element visually. So it typically does not make sense to change the styles of the parent element when the top layer element is hovered or activated, for example.\n\nThe customizable select implementation shipped in Chromium has this logic hard-coded for the specific case of the select `::picker()` popover. That special case logic is being removed in favor of the more general behavior with this feature.", "markdown_fields": [], "blink_components": ["Blink>CSS"], "star_count": 56, "search_tags": ["top layer", "popover"], "created": {"by": "masonfreed@google.com", "when": "2026-04-04 00:51:13.442271"}, "updated": {"by": "masonfreed@google.com", "when": "2026-05-07 00:34:32.146926"}, "category": "CSS", "category_int": 15, "feature_notes": null, "web_feature": "user-action-pseudos", "is_official_web_feature": true, "webdx_usecounter_enum": null, "enterprise_feature_categories": [], "enterprise_product_category": 0, "is_releasenotes_content_reviewed": false, "is_releasenotes_publish_ready": false, "stages": [{"id": 6230768415277056, "created": "2026-04-04 00:51:13.944511", "feature_id": 6296574159355904, "stage_type": 320, "display_name": null, "pm_emails": [], "tl_emails": [], "ux_emails": [], "te_emails": [], "intent_thread_url": null, "announcement_url": null, "experiment_goals": null, "experiment_risks": null, "origin_trial_id": null, "origin_trial_feedback_url": null, "ot_action_requested": false, "ot_approval_buganizer_component": null, "ot_approval_buganizer_custom_field_id": null, "ot_approval_criteria_url": null, "ot_approval_group_email": null, "ot_chromium_trial_name": null, "ot_description": null, "ot_display_name": null, "ot_documentation_url": null, "ot_emails": [], "ot_feedback_submission_url": null, "ot_has_third_party_support": false, "ot_is_critical_trial": false, "ot_is_deprecation_trial": false, "ot_owner_email": null, "ot_requester_email": null, "ot_require_approvals": false, "ot_use_counter_bucket_number": null, "ot_webfeature_use_counter": null, "extensions": [], "experiment_extension_reason": null, "ot_stage_id": null, "finch_url": null, "rollout_milestone": null, "rollout_platforms": [], "rollout_details": null, "rollout_impact": 2, "rollout_stage_plan": null, "enterprise_policies": [], "desktop_first": null, "android_first": null, "ios_first": null, "webview_first": null, "desktop_last": null, "android_last": null, "ios_last": null, "webview_last": null}, {"id": 4848480398999552, "created": "2026-04-04 00:51:13.999952", "feature_id": 6296574159355904, "stage_type": 330, "display_name": null, "pm_emails": [], "tl_emails": [], "ux_emails": [], "te_emails": [], "intent_thread_url": null, "announcement_url": null, "experiment_goals": null, "experiment_risks": null, "origin_trial_id": null, "origin_trial_feedback_url": null, "ot_action_requested": false, "ot_approval_buganizer_component": null, "ot_approval_buganizer_custom_field_id": null, "ot_approval_criteria_url": null, "ot_approval_group_email": null, "ot_chromium_trial_name": null, "ot_description": null, "ot_display_name": null, "ot_documentation_url": null, "ot_emails": [], "ot_feedback_submission_url": null, "ot_has_third_party_support": false, "ot_is_critical_trial": false, "ot_is_deprecation_trial": false, "ot_owner_email": null, "ot_requester_email": null, "ot_require_approvals": false, "ot_use_counter_bucket_number": null, "ot_webfeature_use_counter": null, "extensions": [], "experiment_extension_reason": null, "ot_stage_id": null, "finch_url": null, "rollout_milestone": null, "rollout_platforms": [], "rollout_details": null, "rollout_impact": 2, "rollout_stage_plan": null, "enterprise_policies": [], "desktop_first": 148, "android_first": 148, "ios_first": null, "webview_first": null, "desktop_last": null, "android_last": null, "ios_last": null, "webview_last": null}, {"id": 5195110871597056, "created": "2026-04-04 00:51:14.056519", "feature_id": 6296574159355904, "stage_type": 360, "display_name": null, "pm_emails": [], "tl_emails": [], "ux_emails": [], "te_emails": [], "intent_thread_url": null, "announcement_url": null, "experiment_goals": null, "experiment_risks": null, "origin_trial_id": null, "origin_trial_feedback_url": null, "ot_action_requested": false, "ot_approval_buganizer_component": null, "ot_approval_buganizer_custom_field_id": null, "ot_approval_criteria_url": null, "ot_approval_group_email": null, "ot_chromium_trial_name": null, "ot_description": null, "ot_display_name": null, "ot_documentation_url": null, "ot_emails": [], "ot_feedback_submission_url": null, "ot_has_third_party_support": false, "ot_is_critical_trial": false, "ot_is_deprecation_trial": false, "ot_owner_email": null, "ot_requester_email": null, "ot_require_approvals": false, "ot_use_counter_bucket_number": null, "ot_webfeature_use_counter": null, "extensions": [], "experiment_extension_reason": null, "ot_stage_id": null, "finch_url": null, "rollout_milestone": null, "rollout_platforms": [], "rollout_details": null, "rollout_impact": 2, "rollout_stage_plan": null, "enterprise_policies": [], "desktop_first": 149, "android_first": 149, "ios_first": null, "webview_first": 149, "desktop_last": null, "android_last": null, "ios_last": null, "webview_last": null}], "accurate_as_of": "2026-05-04 16:31:40.733317", "creator_email": "masonfreed@google.com", "updater_email": "masonfreed@google.com", "owner_emails": ["masonf@chromium.org"], "editor_emails": ["masonfreed@google.com"], "cc_emails": [], "spec_mentor_emails": [], "unlisted": false, "deleted": false, "editors": ["masonfreed@google.com"], "cc_recipients": [], "spec_mentors": [], "creator": "masonfreed@google.com", "feature_type": "No developer-visible change", "feature_type_int": 2, "intent_stage": "None", "intent_stage_int": 0, "active_stage_id": 5195110871597056, "bug_url": "https://crbug.com/407769114", "launch_bug_url": null, "new_crbug_url": "https://bugs.chromium.org/p/chromium/issues/entry?components=Blink>CSS&blocking=407769114&cc=masonf@chromium.org", "screenshot_links": [], "first_enterprise_notification_milestone": null, "enterprise_impact": 1, "breaking_change": false, "confidential": false, "shipping_year": 2026, "flag_name": null, "finch_name": "UserActionPseudosStopAtTopLayer", "non_finch_justification": null, "ongoing_constraints": null, "rollout_plan": 0, "rollout_plan_displayname": "Will ship enabled for all users", "motivation": "Without this feature, the user action pseudo elements can feel \"broken\", since they apply to elements that are disjoint from the UI being interacted with. Top layer elements are very commonly displayed in a different location than their parent elements, by their nature.", "devtrial_instructions": null, "activation_risks": null, "measurement": null, "availability_expectation": null, "adoption_expectation": null, "adoption_plan": null, "initial_public_proposal_url": null, "explainer_links": [], "requires_embedder_support": false, "spec_link": "https://www.w3.org/TR/selectors-4/#useraction-pseudos", "api_spec": false, "automation_spec": false, "interop_compat_risks": "While this is a behavioral change, in that the user action pseudos will no longer match across top layer boundaries, it is very unlikely to cause compat issues, because the old behavior was so broken. It is unlikely that a site is relying on that behavior intentionally. While it's possible they unintentionally did so, but in that case, this feature will effectively be a bug fix for those sites.", "all_platforms": null, "all_platforms_descr": null, "non_oss_deps": null, "anticipated_spec_changes": null, "security_risks": null, "ergonomics_risks": null, "wpt": null, "wpt_descr": null, "webview_risks": null, "devrel_emails": ["devrel-chromestatus-all@google.com"], "debuggability": null, "doc_links": [], "sample_links": [], "prefixed": null, "tags": ["top layer", "popover"], "tag_review": null, "tag_review_status": "Not applicable", "tag_review_status_int": 4, "security_review_status": "Pending", "security_review_status_int": 1, "privacy_review_status": "Pending", "privacy_review_status_int": 1, "security_continuity_id": null, "security_launch_issue_id": null, "updated_display": null, "resources": {"samples": [], "docs": []}, "comments": null, "ff_views": 5, "safari_views": 5, "web_dev_views": 4, "browsers": {"chrome": {"bug": "https://crbug.com/407769114", "blink_components": ["Blink>CSS"], "devrel": ["devrel-chromestatus-all@google.com"], "owners": ["masonf@chromium.org"], "origintrial": false, "prefixed": null, "flag": false, "status": {"text": "Proposed", "val": 2, "milestone_str": "Proposed"}, "announced": true, "desktop": 149, "android": 149, "webview": 149, "ios": null}, "ff": {"view": {"url": null, "notes": null, "text": "No signal", "val": 5}}, "safari": {"view": {"url": null, "notes": null, "text": "No signal", "val": 5}}, "webdev": {"view": {"text": "No signals", "val": 4, "url": null, "notes": null}}, "other": {"view": {"text": null, "val": null, "url": null, "notes": null}}}, "standards": {"spec": "https://www.w3.org/TR/selectors-4/#useraction-pseudos", "maturity": {"text": "Specification currently under development in a Working Group", "short_text": "Working draft", "val": 4}}, "is_released": false, "is_enterprise_feature": false, "experiment_timeline": null, "ai_test_eval_report": null, "ai_test_eval_run_status": null, "ai_test_eval_status_timestamp": null}