← Back tothis vs that

border vs outline

Written byPhuoc Nguyen
Created
17 Jun, 2020
Last updated
19 Jul, 2023
Category
CSS
Contributors
Hex-4

Differences

  1. Outlines don't take up space meaning that using outlines or not doesn't affect the dimensions of the outlined element.
  2. `border` supports rounded corners with the `border-radius` property, meanwhile `outline` doesn't.
  3. 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`.
  4. The outlines may be non-rectangular.
    In the sample code below, the outlines are shown in a non-rectangular shape:
    html
    <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:
css
/* 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 color
    css
    a:focus {
    background: ...;
    }
  • Set the text color:
    css
    a:focus {
    color: ...;
    }
  • Using both approaches
    css
    a:focus {
    background: ...;
    color: ...;
    }
  • Use a different style to normalize the look and feel of outline across browsers such as
    css
    a: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:
js
// 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:
css
.intent-mouse a:focus {
outline: 0;
}
Initially, the CSS class is added to the body element:
html
<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:
js
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:
js
[].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:
js
[].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:
js
// Set the outline for links only
[].forEach.call(
document.querySelectorAll('a'),
...
);
If you found this post helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

Questions? 🙋

Do you have any questions about front-end development? If so, feel free to create a new issue on GitHub using the button below. I'm happy to help with any topic you'd like to learn more about, even beyond what's covered in this post.
While I have a long list of upcoming topics, I'm always eager to prioritize your questions and ideas for future content. Let's learn and grow together! Sharing knowledge is the best way to elevate ourselves 🥷.
Ask me questions

Recent posts ⚡

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