Support :focus-visible CSS pseudoclass

Michael Strauß michaelstrau2 at gmail.com
Sun Jun 6 00:59:02 UTC 2021


I'd like to try to move this proposal forward, so here's a JEP-like
summary of the proposal:



Summary
-------
Add the `javafx.scene.Node.focusVisible` property, as well as the
"focus-visible" CSS pseudoclass.


Motivation
----------
The W3C CSS Selectors Level 4 specification defines three
focus-related pseudo-classes:
"focus", which applies to a node that currently accepts keyboard or mouse input;
"focus-visible", which applies to a focused node that visibly
indicates focus, and
"focus-within", which applies to a focused node and any of its parents.

JavaFX currently implements the "focused" property only, which
corresponds to the "focus" CSS pseudoclass.

However, many contemporary UI designs do not always indicate focus in
the same way that the built-in JavaFX themes do. For example, the
Windows 10 theme or modern "Fluent" design implementations generally
only indicate the focused element as a consequence of keyboard input.
There are also "Material" design implementations with the same
behavior.

Adding a "focusVisible" property and the corresponding "focus-visible"
pseudoclass to JavaFX will enable application developers to create
modern themes that differentiate between logical input focus and
visual focus indication.


Description
-----------
A new property will be added to javafx.scene.Node:

    public final boolean isFocusVisible()
    public final ReadOnlyBooleanProperty focusVisibleProperty()

This new property will also toggle the "focus-visible" pseudo-class on
its scene graph node.

The property value is set in conjunction with the value of
"Node.focused" as an atomic operation, so it will not be possible for
listeners to observe inconsistent values. The value of
"Node.focusVisible" will be determined by tracking the input modality
that caused a node to acquire focus.

The W3C CSS specification includes some suggestions for the heuristics
used to determine whether or not focus should be indicated:
https://drafts.csswg.org/selectors-4/#focus-visible-pseudo

For JavaFX, "Node.focusVisible" would be set in addition to
"Node.focused" if a scene graph node gained focus as a consequence of
keyboard input. In all other cases, "Node.focusVisible" would not be
set on a node.

Additionally, the value of "Node.focusVisible" is cleared if the node
receives interaction with mouse or touch.

One of the W3C suggestions should not be implemented for JavaFX:

> If the previously-focused element indicated focus, and a script causes focus to move elsewhere, the newly focused element should indicate focus.
> Conversely, if the previously-focused element did not indicate focus, and a script causes focus to move elsewhere, the newly focused element should also not indicate focus.

This behavior is difficult to implement in JavaFX, because there is no
way for a node to know whether or not it gained focus
programmatically, or as a result of a control skin invoking
Node.requestFocus(). Supporting this scenario would require adding new
public API and potentially changing lots of skins to account for the
distinction between programmatic and mouse-based focus traversal. The
impact on existing code would most likely be too large for a very
marginal benefit.


Alternatives
------------
As an alternative to implementing this feature, modality-aware focus
indication might be implemented in a JavaFX application by installing
event handlers on individual controls or on the Scene (in order to
intercept the TAB key) and monitoring the "focused" property (or
"focusOwner", respectively).

As another alternative to using built-in rules to determine the value
of the "focusVisible" property, there could be an API that allows
application developers to change these rules. However, it appears that
the benefit of doing to is very marginal, while the effort could be
very significant.


More information about the openjfx-dev mailing list