Description
Current behavior
When tabbing and arrowing between the scroll-buttons and scroll-markers, focus events fire but the document.activeElement
does not change. Even worse, event.target
and event.relatedTarget
directly reference the CSS pseudo-elements and do not match document.activeElement
.
Problem
A common part of writing focus handling logic is comparing target
and relatedTarget
to activeElement
in focus events; if overflow scroll buttons and scroll markers depart from how those are expected to work in all other focus-affecting user interactions, it will almost certainly both break existing focus management scripts and also make it either significantly harder or impossible to write logic handling UI that contains carousels in the future.
The other issue is that saving a reference to event.target
and calling .focus()
on it also results in a console error (since pseudo-elements aren't HTMLElement
s and don't support the .focus
method). This is a very common way to handle saving the element to return focus to when something like a dialog, popup, or other type of UI opens and then closes.
I can't think of another instance where a focus event's target
or relatedTarget
would be an Element
that is not an HTMLElement
, but there could easily be an edge case I'm not thinking of. Even if there is, I'd lean against adding another one.
Possible solutions
I'm sure there are more potential ways to resolve this, these are just my initial thoughts:
- No focus events fire when focus changes between pseudo-elements
- Pseudo-elements are exposed and can be referenced by a selector in some way
- Focus events fire, but the
event.target
andevent.relatedTarget
are the same, anddocument.activeElement
would not change
I'd lean towards (1), since it matches what happens in controls like <input type="date">
, and presents the fewest high-level changes (at least that I can think of). The second option would require some pretty significant updates to the DOM Node
interface, and the third would break a pretty longstanding assumption about how focus events work, with potentially wide-reaching and breaking effects on existing focus-related scripting.
With any of the solutions, I don't think it's a good idea for event.target
and event.relatedTarget
to continue directly referencing pseudo-elements.