Support the :focus-within pseudo-class - #615
Open
maurerdietmar wants to merge 2 commits into
Open
Conversation
maurerdietmar
force-pushed
the
focus-within
branch
from
August 7, 2026 09:37
4a767ec to
37f716a
Compare
nicoburns
requested changes
Aug 7, 2026
nicoburns
left a comment
Member
There was a problem hiding this comment.
This needs to use regular ancestors (node.parent) rather than layout ancestors (node.layout_parent) as focus pertains to the DOM elements tree rather than the layout tree.
This also needs to handle updating :focus-within when an element is moved within the tree.
compare_document_order builds root-first DOM ancestor chains with a private helper. Interaction state updates need the same walk, so give it a public name next to node_layout_ancestors, an Option-taking variant, and tolerance for freed slots via get_node, matching nearest_surviving_element_ancestor. Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Selector matching for :focus-within was stubbed to false and no element state was maintained for it, so styles keyed on it (a common pattern for form field focus rings, where the visible border lives on a wrapper around the input) never applied. Track ElementState::FOCUS_WITHIN on the focused element and all of its DOM ancestors, using the same ancestor-path diffing as hover so a focus move only restyles the non-shared parts of the two chains. The DOM chain rather than the layout chain, because focus pertains to the DOM tree: the layout chain skips display: contents ancestors, and its links do not exist before the first layout pass, which is when autofocus fires. The state follows tree changes around the focused node: it is cleared on refocus, clear_focus and removal, and transferred from the old ancestor chain to the new one when a subtree containing the focus is moved to a different parent, including out of the document. Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
maurerdietmar
force-pushed
the
focus-within
branch
from
August 7, 2026 15:01
37f716a to
76c17eb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Selector matching for :focus-within was stubbed to false and no element state was maintained for it, so styles keyed on it (a common pattern for form field focus rings, where the visible border lives on a wrapper around the input) never applied.
Track ElementState::FOCUS_WITHIN on the focused element and all of its ancestors, using the same ancestor-path diffing as hover so a focus move only restyles the non-shared parts of the two chains. Cleared on refocus, clear_focus, and removal of the focused node.
WPT results
No changes in test results compared to
main.Generated by the WPT workflow.