This is a common concern.
The default outline that browsers render is ugly.
See this for example:
form,
label {
margin: 1em auto;
}
label {
display: block;
}
<form>
<label>Click to see the input below to see the outline</label>
<input type="text" placeholder="placeholder text" />
</form>
The most common "fix" that most recommend is outline:none
- which if used incorrectly - is disaster for accessibility.
So...of what use is the outline anyway?
There's a very dry-cut website I found which explains everything well.
It provides visual feedback for links that have "focus" when
navigating a web document using the TAB key (or equivalent). This is
especially useful for folks who can't use a mouse or have a visual
impairment. If you remove the outline you are making your site
inaccessible for these people.
Ok, let's try it out same example as above, now use the TAB
key to navigate.
form,
label {
margin: 1em auto;
}
label {
display: block;
}
<form>
<label>Click on this text and then use the TAB key to naviagte inside the snippet.</label>
<input type="text" placeholder="placeholder text" />
</form>
Notice how you can tell where the focus is even without clicking the input?
Now, let's try outline:none
on our trusty <input>
So, once again, use the TAB
key to navigate after clicking the text and see what happens.
form,
label {
margin: 1em auto;
}
label {
display: block;
}
input {
outline: none;
}
<form>
<label>Click on this text and then use the TAB key to naviagte inside the snippet.</label>
<input type="text" placeholder="placeholder text" />
</form>
See how it's more difficult to figure out where the focus is? The only telling sign is the cursor blinking. My example above is overly simplistic. In real-world situations, you wouldn't have only one element on the page. Something more along the lines of this.
.wrapper {
width: 500px;
max-width: 100%;
margin: 0 auto;
}
form,
label {
margin: 1em auto;
}
label {
display: block;
}
input {
outline: none;
}
<div class="wrapper">
<form>
<label>Click on this text and then use the TAB key to naviagte inside the snippet.</label>
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
</form>
<form>
First name:<br>
<input type="text" name="firstname"><br> Last name:<br>
<input type="text" name="lastname">
</form>
<form>
<input type="radio" name="gender" value="male" checked> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<input type="radio" name="gender" value="other"> Other
</form>
<form>
<label for="GET-name">Name:</label>
<input id="GET-name" type="text" name="name">
</form>
<form>
<label for="POST-name">Name:</label>
<input id="POST-name" type="text" name="name">
</form>
<form>
<fieldset>
<legend>Title</legend>
<input type="radio" name="radio" id="radio">
<label for="radio">Click me</label>
</fieldset>
</form>
</div>
Now compare that to the same template if we keep the outline:
.wrapper {
width: 500px;
max-width: 100%;
margin: 0 auto;
}
form,
label {
margin: 1em auto;
}
label {
display: block;
}
<div class="wrapper">
<form>
<label>Click on this text and then use the TAB key to naviagte inside the snippet.</label>
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
</form>
<form>
First name:<br>
<input type="text" name="firstname"><br> Last name:<br>
<input type="text" name="lastname">
</form>
<form>
<input type="radio" name="gender" value="male" checked> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<input type="radio" name="gender" value="other"> Other
</form>
<form>
<label for="GET-name">Name:</label>
<input id="GET-name" type="text" name="name">
</form>
<form>
<label for="POST-name">Name:</label>
<input id="POST-name" type="text" name="name">
</form>
<form>
<fieldset>
<legend>Title</legend>
<input type="radio" name="radio" id="radio">
<label for="radio">Click me</label>
</fieldset>
</form>
</div>
So we have established the following
- Outlines are ugly
- Removing them makes life more difficult.
So what's the answer?
Remove the ugly outline and add your own visual cues to indicate focus.
Here's a very simple example of what I mean.
I remove the outline and add a bottom border on :focus and :active. I also remove the default borders on the top, left and right sides by setting them to transparent on :focus and :active (personal preference)
form,
label {
margin: 1em auto;
}
label {
display: block;
}
input {
outline: none
}
input:focus,
input:active {
border-color: transparent;
border-bottom: 2px solid red
}
<form>
<label>Click to see the input below to see the outline</label>
<input type="text" placeholder="placeholder text" />
</form>
So, we try the approach above with our "real-world" example from earlier:
.wrapper {
width: 500px;
max-width: 100%;
margin: 0 auto;
}
form,
label {
margin: 1em auto;
}
label {
display: block;
}
input {
outline: none
}
input:focus,
input:active {
border-color: transparent;
border-bottom: 2px solid red
}
<div class="wrapper">
<form>
<label>Click on this text and then use the TAB key to naviagte inside the snippet.</label>
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
<input type="text" placeholder="placeholder text" />
</form>
<form>
First name:<br>
<input type="text" name="firstname"><br> Last name:<br>
<input type="text" name="lastname">
</form>
<form>
<input type="radio" name="gender" value="male" checked> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<input type="radio" name="gender" value="other"> Other
</form>
<form>
<label for="GET-name">Name:</label>
<input id="GET-name" type="text" name="name">
</form>
<form>
<label for="POST-name">Name:</label>
<input id="POST-name" type="text" name="name">
</form>
<form>
<fieldset>
<legend>Title</legend>
<input type="radio" name="radio" id="radio">
<label for="radio">Click me</label>
</fieldset>
</form>
</div>
This can be extended further by using external libraries that build on the idea of modifying the "outline" as opposed to removing it entirely like Materialize
You can end up with something that is not ugly and works with very little effort
body {
background: #444
}
.wrapper {
padding: 2em;
width: 400px;
max-width: 100%;
text-align: center;
margin: 2em auto;
border: 1px solid #555
}
button,
.wrapper {
border-radius: 3px;
}
button {
padding: .25em 1em;
}
input,
label {
color: white !important;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.1/css/materialize.min.css" />
<div class="wrapper">
<form>
<input type="text" placeholder="Enter Username" name="uname" required>
<input type="password" placeholder="Enter Password" name="psw" required>
<button type="submit">Login</button>
</form>
</div>