18

I was looking into the default functionality of form elements and what different states they have between browsers. I found something quite strange. This has been tested in different browsers and the results are similar. The screenshots below are from Chrome v44.0.2403.155m (64-bit Windows).

Ok, so the problem is with focus states of buttons. Below you will see a default form with no css styling. I click on the first input and then use the Tab Key to tab down the form elements. In chrome you get a light blue outline applied to every element you tab onto.

enter image description here

Notice that when I click on the button with the mouse there is no light blue "focus" state it only happens when I tab onto it.

I presumed this was just using :focus, and if I styled button:focus then I would be able to replicate this default behavior. Tab onto a button it highlights, click on a button it does not. Have a look at this styled version of the form...

enter image description here

When I click on the first input and tab down it does the same thing, my custom outline is shown (this is fine). However, notice when I click on the button, it is applying the :focus state to it. This is not the same as the default behavior. In the un-styled version, a click does not apply a focus state.

The only CSS I am using on the button is...

input:focus, button:focus {
    outline: 2px solid green;
}

Here is a demo: http://jsfiddle.net/oy83s4up

How do I make sure there is no outline when the button is clicked, only when it is tabbed?. Also, by default when a button is focused with the tab key, even when it is clicked, the outline still remains, this is also functionality I want to replicate.

Note: I am not looking for a JS work around, The first animation is default behavior in the browser. Surely it can replicated with css only? If not, then it is a bug.

Rvervuurt
  • 8,589
  • 8
  • 39
  • 62
Bruffstar
  • 1,249
  • 1
  • 10
  • 18
  • If you don’t want the blue outline for the submit button – well, then don’t format `button:focus` with an outline …? Not really clear to me what you’re asking here. – CBroe Aug 17 '15 at 09:13
  • 3
    @CBroe By default, when tabbing to the button, the outline is shown. When clicking on it, though, the outline is not shown. This is the behaviour he wants. However, as soon as you style the button (in any way) this behaviour changes. The outline is still shown when the button is tabbed to, but now the outline is also shown on click. The question is: How to remove the outline on click, but not when tabbed (as was the default). – Lionel Aug 17 '15 at 09:19
  • Great animations, chapeau! :) – Sz. Mar 16 '18 at 16:39

3 Answers3

6

Interesting question!

What I noticed when inspecting the button through Inspect Element and triggering a :focus, the button gets the style outline: -webkit-focus-ring-color auto 5px;.

enter image description here

This does not create an outline on the button though. (This could be because of Chrome on Mac, since tabbing doesn't create an outline either)

enter image description here

When I add this to the button in the styled form instead of your added outline, it doesn't get the blue dropshadow you get when tabbing through. This weird if you ask me. When I google -webkit-focus-ring-color, I come to this question on SO. In that answer, he writes something about [NSColor keyboardFocusIndicatorColor], which really talks about keyboard focus (tabbing through the form) and not mouse focus.

When googling a bit on focus indicators, I landed on the Wikipedia-page for Focus (computing), containing the following piece of text:

By convention, the tab key is used to move the focus to the next focusable component and shift + tab to the previous one. When graphical interfaces were first introduced, many computers did not have mice, so this alternative was necessary. This feature makes it easier for people that have a hard time using a mouse to use the user interface.

This tells me that the focus on button only shows up with a keyboard press, because in the beginning it was necessary to show what element is focused on, while now with a mouse it's clear what is being focused on, since you are actively moving the mouse to the button.

Community
  • 1
  • 1
Rvervuurt
  • 8,589
  • 8
  • 39
  • 62
  • Thanks for your answer, I also found some of the stuff you mentioned while researching. But I could not find anywhere that explained why the behavior is different when you start to add css to the button. – Bruffstar Aug 17 '15 at 11:14
  • 1
    The only logical explanation I have is that you KNOW where you click when you are moving the mouse, while you might not when you are tabbing through a website :) – Rvervuurt Aug 17 '15 at 11:20
1

I don't know if it's possible using only css, but with JS, it is.

Green border is not shown when clicked on the button, but when the button is focused with tab.

var submit = document.getElementById("submit");

var tabbing = false;

window.onkeyup = function (e) {
    if (e.keyCode == 9) {
        tabbing = true;
    }
}

submit.onfocus = function (e) {
    if (tabbing) {
        this.classList.add("tabbed");
    }
};

submit.onblur = function () {
    this.classList.remove("tabbed");
    tabbing = false;
};
#submit.tabbed:focus {
    outline: 2px solid green;
}
<label>Name:</label>
<input type="text" />
<br>
<label>Pass:</label>
<input type="password" />
<br>
<label>Save Password:</label>
<input type="checkbox" />
<br>
<br>
<button id="submit">Submit</button>
akinuri
  • 10,690
  • 10
  • 65
  • 102
  • Thank you for this, but I am not looking for a JS solution. The first animation in my question is default behavior in the browser. Surely it can replicated with css only. If not, then it might a bug. – Bruffstar Aug 17 '15 at 11:12
  • 1
    I'm looking for a way of using CSS only too, although I don't think this is currently possible without hacks. See this link, which suggests using the active state, with a CSS3 transition - http://vanseodesign.com/css/click-events/ (unfortunately I don't think this would go down to well in the application I'm working on, maybe for a freelance project this would be fine). – Nick Taras Dec 16 '15 at 22:39
1

2018 Answer: Use :focus-visible. It's currently a W3C proposal for styling keyboard-only focus using CSS. Until major browsers support it, you can use this robust polyfill. It doesn't require adding extra elements or altering the tabindex.

/* Remove outline for non-keyboard :focus */
*:focus:not(.focus-visible) {
  outline: none;
}

/* Optional: Customize .focus-visible */
.focus-visible {
  outline-color: lightgreen;
}

I also wrote a more detailed post with some demo just in case you need more info.

Aaron Noel De Leon
  • 1,139
  • 10
  • 9