How to Trigger the :Active Pseudoclass on Keyboard 'Enter' Press? (Using Only CSS)

How to trigger the :active pseudoclass on keyboard 'enter' press? (using only CSS)

Good question!

Yeah, you can't do this anymore.

A long time ago MSIE treated :active like :focus so there was sort of a way to accomplish this with hyperlinks (this was before gigabit internet speeds and when browsers didn't do a good job of showing load-in-progress except for a dumb waving flag or something).

Run the below Snippet to see the behavior in action:

  • input type='button' can be activated with ENTER or SPACE
  • Holding down SPACE on a button will show the :active style (except for FireFox; this looks like FF bug since it works OK for mousedown)
  • Holding down ENTER on a button will repeatedly trigger onclick every time your keyboard sends the character.
  • Holding down SPACE on a button will trigger onclick only if the SPACE key is released while still focused on the button. (For example, you can simulate mouse click this way: tab to a button, hold down space, then hit tab again and release it to cancel the click.)
  • Hyperlinks can be activated with ENTER only.
  • Clicking on hyperlinks will show :active style, using ENTER (or touch) will not.

document.getElementById('t1').focus(); // set focus for easier demo
:active{   color: Red;}
<input type='text' id='t1' value='Set focus and hit tab'/><a href='javascript:;' onclick='console.log("Hyperlink")'>Hyperlink</a><input type='button' value='Button' onclick='console.log("Button")'/>

Can I have an onclick effect in CSS?

The closest you'll get is :active:

#btnLeft:active {
width: 70px;
height: 74px;
}

However this will only apply the style when the mouse button is held down. The only way to apply a style and keep it applied onclick is to use a bit of JavaScript.

Enable :focus only on keyboard use (or tab press)

Update: This issue may no longer be relevant

Some other posters have mentioned the :focus-visible pseudo class - which now has decent browser support...

I would like to add, that based on the spec which covers the :focus-visible pseudo class, browsers should now only indicate focus when it is helpful to the user - such as in cases where the user interacts with the page via a keyboard or some other non-pointing device

This basically means that the original issue is no longer relevant, because now, when a user clicks/taps a button (or another focusable element), the User Agent won't show the focus ring anymore - even though the button is focused - because in this case the focus ring isn't helpful to the user.

From the spec:

While the :focus pseudo-class always matches the currently-focused
element, UAs only sometimes visibly indicate focus (such as by
drawing a “focus ring”), instead using a variety of heuristics to
visibly indicate the focus only when it would be most helpful to the
user. The :focus-visible pseudo-class matches a focused element in
these situations only...

Indeed, as of version 90, Chromium’s User Agent stylesheet switched from :focus to :focus-visible, and as a result of this change, button clicks and taps no longer invoke focus rings

Also, as of version 87, Firefox also uses :focus-visible on their User Agent style.

All that being said, if custom focus styles are needed, since focus styles have now shifted from :focus to :focus-visible, when overriding the default styles with custom focus styles - the :focus-visible pseudo class should be used.

Something like this:

button:focus-visible {
/* remove default focus style */
outline: none;
/* custom focus styles */
box-shadow: 0 0 2px 2px #51a7e8;
color: lime;
}

Backwards Compatibility:

The possible problem with using :focus-visible like this, is that browsers which don't support :focus-visible, will show the default focus ring, which may not be clear or visible - depending on the design.

Šime Vidas, in this article, describes a viable strategy to currently use the :focus-visible pseudo class - which would work even in browsers which don't yet support :focus-visible -

A good way to start using :focus-visible today is to define the focus
styles in a :focus rule and then immediately undo these same styles in
a :focus:not(:focus-visible) rule. This is admittedly not the most
elegant and intuitive pattern, but it works well in all browsers:

Browsers that don’t support :focus-visible use the focus styles
defined in the :focus rule and ignore the second style rule completely
(because :focus-visible is unknown to them).

In browsers that do support :focus-visible, the second style rule
reverts the focus styles defined in the :focus rule if the
:focus-visible state isn’t active as well. In other words, the focus
styles defined in the :focus rule are only in effect when
:focus-visible is also active.

button:focus {
outline: none;
background: #ffdd00; /* gold */
}

button:focus:not(:focus-visible) {
background: white; /* undo gold */
}

Original Answer:

This excellent article by Roman Komarov poses a viable solution for achieving keyboard-only focus styles for buttons, links and other container elements such as spans or divs (which are artificially made focusable with the tabindex attribute)

The Solution:

button {
-moz-appearance: none;
-webkit-appearance: none;
background: none;
border: none;
outline: none;
font-size: inherit;
}

.btn {
all: initial;
margin: 1em;
display: inline-block;
}

.btn__content {
background: orange;
padding: 1em;
cursor: pointer;
display: inline-block;
}

/* Fixing the Safari bug for `<button>`s overflow */
.btn__content {
position: relative;
}

/* All the states on the inner element */
.btn:hover > .btn__content {
background: salmon;
}

.btn:active > .btn__content {
background: darkorange;
}

.btn:focus > .btn__content {
box-shadow: 0 0 2px 2px #51a7e8;
color: lime;
}

/* Removing default outline only after we've added our custom one */
.btn:focus,
.btn__content:focus {
outline: none;
}
<h2>Keyboard-only focus styles</h2>

<button id="btn" class="btn" type="button">
<span class="btn__content" tabindex="-1">
I'm a button!
</span>
</button>

<a class="btn" href="#x">
<span class="btn__content" tabindex="-1">
I'm a link!
</span>
</a>

<span class="btn" tabindex="0">
<span class="btn__content" tabindex="-1">
I'm a span!
</span>
</span>

<p>Try clicking any of the the 3 focusable elements above - no focus styles will show</p>
<p>Now try tabbing - behold - focus styles</p>


Related Topics



Leave a reply



Submit