border vs outline
Written byPhuoc Nguyen
Category
CSS
Created
17 Jun, 2020
Last updated
19 Jul, 2023
#Differences
-
Outlines don't take up space meaning that using outlines or not doesn't affect the dimensions of the outlined element.
-
`border`
supports rounded corners with the`border-radius`
property, meanwhile`outline`
doesn't. -
We can define the border style for each side via the
`border-top`
,`border-left`
,`border-bottom`
and`border-right`
properties. It's not possible to set the style for a particular side with`outline`
. -
The outlines may be non-rectangular.In the sample code below, the outlines are shown in a non-rectangular shape:<div>...<span style="outline: 0.25rem solid blue"> ... </span>...</div>
#Good practice
The primary purpose of
`outline`
is to support accessibility. It provides visual feedback for links, buttons when users navigate between them with the Tab key.You shouldn't remove outline style from elements when they are being focused. Setting
`outline: none`
or `outline: 0`
will make the page inaccessible for the people who don't use mouse or have a visual impairment.One of the first and popular CSS reset library removed the outline, but the author leaves a comment that reminds us to define the focus styles:
/* remember to define focus styles! */
:focus {
outline: 0;
}
But this reset was removed in the latest version.
If you have to remove the outline style, then it's recommended to provide alternative styles.
Here are some pure CSS based solutions:
-
Set the background colora:focus {background: ...;}
-
Set the text color:a:focus {color: ...;}
-
Using both approachesa:focus {background: ...;color: ...;}
-
Use a different style to normalize the look and feel of outline across browsers such asa:focus {outline: thin dotted;}
There's another approach which uses JavaScript to handle the events. If we detect there is a mouse event, then remove the outline style.
In the other case, if a keyboard event is detected then we restore the outline style.
Here is a piece of code demonstrating this idea:
// Append a custom style to `head`
const style = document.createElement('style');
document.head.appendChild(style);
const remove = () => (style.innerHTML = ':focus { outline: 0 }');
const restore = () => (style.innerHTML = '');
// Remove the outline initially
remove();
document.addEventListener('mousedown', () => restore());
document.addEventListener('keydown', () => remove());
Some other websites such as Github use a similar approach. Starting with a CSS class that resets the outline property:
.intent-mouse a:focus {
outline: 0;
}
Initially, the CSS class is added to the body element:
<body class="intent-mouse">
...
</body>
By detecting the keyboard and mouse events, we can remove the class or add it back to the body element:
document.addEventListener('mousedown', () => {
document.body.classList.add('intent-mouse');
});
document.addEventListener('keydown', (e) => {
// If users press the Tab key
// then we assume that they intent to use the keyboard to navigate
if (e.key === 'Tab') {
document.body.classList.remove('intent-mouse');
}
});
#Tip
The
`outline`
property is useful when you want to visualize elements on the page.
In the following sample code, we iterate over all the elements and
set the `outline`
property with a random hex color:[].forEach.call(document.querySelectorAll('*'), (ele) => {
const color = `#\${Math.random().toString(16).slice(2, 8).padEnd(6, '0')}`;
ele.style.outline = `1px solid \${color}`;
});
Of course, you will need an opposite command to reset the
`outline`
property:[].forEach.call(document.querySelectorAll('*'), (ele) => ele.style.removeProperty('outline'));
You can change the selector from
`*`
to whatever you want to match the set of particular elements, for example:// Set the outline for links only
[].forEach.call(
document.querySelectorAll('a'),
...
);
Questions? 🙋
Do you have any questions? Not just about this specific post, but about any topic in front-end development that you'd like to learn more about? If so, feel free to send me a message on Twitter or send me an email. You can find them at the bottom of this page.
I have a long list of upcoming posts, but your questions or ideas for the next one will be my top priority. Let's learn together! Sharing knowledge is the best way to grow 🥷.
Recent posts ⚡
Copy the content of an element to your clipboard
01 Oct, 2023
Make a text area fit its content automatically
30 Sep, 2023
Quickly insert alternate characters while typing
30 Sep, 2023
Zebra-like background
30 Sep, 2023
Add autocomplete to your text area
28 Sep, 2023
Linear scale of a number between two ranges
28 Sep, 2023
Highlight the current line in a text area
27 Sep, 2023
Create your own custom cursor in a text area
27 Sep, 2023
Mirror a text area for improving user experience
26 Sep, 2023
Display the line numbers in a text area
24 Sep, 2023
Select a given line in a text area
24 Sep, 2023
Newsletter 🔔
If you're into front-end technologies and you want to see more of the content I'm creating, then you might want to consider subscribing to my newsletter.
By subscribing, you'll be the first to know about new articles, products, and exclusive promotions.
Don't worry, I won't spam you. And if you ever change your mind, you can unsubscribe at any time.
Phước Nguyễn