Skip to content

:focus-within edge cases with DOM mutation and focus moves from within blur/focus event listeners #11835

@emilio

Description

@emilio

What is the issue with the HTML Standard?

Consider a simple test-case like:

<div id=parent>
  <input id=a>
  <input id=b>
</div>
<input id=c>

When moving focus from a to b, browsers (at least Gecko and Chromium) try to keep the :focus-within state of #parent. Problem is, however, that focus movement is not atomic. The blur event handler of a could move focus to c (so could focusout etc).

Both Firefox and Chromium deal wrongly with that case right now (and other similar cases), see Mozilla bug 1996182 and Chromium issue 454668198.

I'm fixing some of those issues in that mozilla bug, but I'm not super happy with the solution which amounts to basically fixing up the state after realizing that focus has moved.

It'd be good to define better how these pseudo-classes are managed. The obvious solution would be to update :focus-within atomically (like :focus), but that can actually cause problems too, because it's a common pattern to do something like:

.submenu {
  display: none;

  .parent:hover &,
  &:focus-within { display: block }
}

So if we update it along with :focus, there's an intermediate step when moving between the menu items where a forced layout update could hide the menu, see Mozilla bug 1361301 for an example.

So I think we need a reasonable model that defines when are these pseudo-classes supposed to match. What I'm doing in Firefox is not too hard to spec, but again I don't think it's super nice...

cc @annevk @mfreed7 @smaug----

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions