A common pseudo-class for :hover and :focus

:hover and :focus

We are familiar with the :hover pseudo-class, which targets elements with a pointer entered into them. The MDN docs refer to this state as “when the user designates an element with a pointing device”.

I think limiting :hover to pointing devices was a missed opportunity, partially realized by the adoption of touch screens, and fully realized by attention now directed at keyboard accessibility. This limitation particularly affects keyboards, which must be separately targeted using the :focus pseudo-class.

I suggest a new pseudo-class be introduced that will target all designations of an element, by any means; whether it be done by a mouse or a finger or a keyboard or any other device that can enter into an element.


I suggest the name be :enter. It is harmonious with PointerEvents, and it shares an intrinsic association with keyboards.

1 Like

It’s admittedly more verbose, but :matches(:hover, :focus) already exists. And there’s a proposal to give any selector a shorter name:


@custom-selector :--enter :hover, :focus;
:--enter { /* ... */ }

To clarify, do you mean:

@custom-selector :--enter :matches(:hover, :focus);
:--enter { /* ... */ }

This could definitely start the cowpath to :enter. Related, is :matches a kind of weightless pseudo-class, like :not? If it does add weight, or if a custom selector carries a different weight, then that would definitely make a difference. I presume this is not the case, and not a concern.

1 Like

They’re equivalent, @custom-selector expands to :matches implicitly.

:matches is in Selectors 4. It does not add specificity.

It seem the naming of :hover is misleading. It specifically means elements designated with a pointing device, rather than any form of input. From the CSS4 specification:

The :hover pseudo-class applies while the user designates an element with a pointing device…

Therefore, I would propose that:

The :enter pseudo-class applies while the user designates an element with a keyboard, pointing device, or other form of input.

To test and perhaps implement :enter in the wild, I’ve created a polyfill / prollyfill.

And, thanks to your feedback, Simon, I’ve added a section that describes alternatives to :enter using @custom-selector, :matches, and plain-old :focus and :hover.

Sorry, I didn’t see that you had posted this here until after I read the post to www-style, I would have rather responded here. Is it simply because you frequently do both? I mean, they definitely aren’t the same right - one is about actually selecting with focus which has a particular meaning in tab order and so on, hover is something that seems more purely for visual adornment. In other words, if it is focusable anyway, you could just use focus. If it isn’t focusable, you won’t be able to tab into it or something anyway?

My need is to target and style the instant, pre-:active state of an element. It’s that moment when, as the spec describes it, I designate an element.

For a keyboard, this instant enter event occurs simultaneously with focus.

Pointers experience something similar, as their click event occurs simultaneously with focus.

Developers target both :hover and :focus because they are actually targeting the same conceptual event, the entering into or designating of an element.

Do you think you could share a working example (I looked but didn’t see one in the github) that illustrates how this is a necessary thing? I frequently use them differently because they have sort of different concepts. “designating” in the hover has no change on where the focus is or what the active element is and so on… So If you have designed something which can be focused, it doesn’t matter how you focus on it, it should be good for a11y or mobile or whatever. If it isn’t focusable, I’m trying to understand how you’d use non-mouse devices to operate that so that it is (specifically because you mentioned noticing this during a11y testing in the www-style post and I’m having trouble bridging). To be clear, I’m not saying it’s a bad idea, just that I don’t see what you are seeing and could use help understanding it.

The working example in GitHub is fine.

nav :enter > span {
    background-color: yellow;

Probably one of the most common accessibility oversights is neglecting to apply CSS to the :focus state of links whenever you style the :hover state. How much of a problem this oversight leads to for non-mouse users depends on what CSS is applied to the :hover state. — 456 Berea Street.

The :enter pseudo-class, like the :matches pseudo-class, is for convenience. With :enter, we have one selector that accurately describes and targets elements we intend users to interface with (using any input device).

Since :enter selectors are half of what they are with :focus and :hover, we will have less selector duplication, which means we’ll have better code clarity. These benefits make using :enter very appealing to developers, which might then mean faster adoption, which means less scenarios where a :focus style is neglected, and better experiences for keyboard-wielding users.

How does one designate an element with a keyboard or another form of input? As Brian stated, :hover and :focus are different (and ideally would differ in style, too). What problem will be solved when :hover and :focus are combined into :enter?

But from that same short article you cite, they what I am bringing up:

Then there are techniques that cause major problems because they make content inaccessible to non-mouse users. This can be either because :hover is used on elements that cannot receive keyboard focus, […OR…] because :hover is used to reveal content and no CSS is applied to the :focus state, or a combination

So you’re saying that :enter applies only to focusable elements? It’s some base level thing like ‘indicate’ that says “I dont care how it’s indicated or for what intent, I just want this css to apply always’”? The problem with that is that the markup is very very very often the problem - in other words - keyboard users still can’t actually indicate things that aren’t focusable…