CSS: Strokes — Outlines

CSS Outlines

Learning outcomes:

  • What are outlines
  • The outline property and its individual properties
  • Outlines and accessibility
  • The outline-offset property
  • Differences between outlines and borders

Introduction

In the first CSS spec, CSS Level 1, there was no mention of the concept of outlines around elements. With time, as people came to better understand the web environment (in terms of user interactions), it became clear that there definitely was such a need.

Ultimately, the second major specification, CSS Level 2, was drafted and, amongst many other features, it put forth the idea of outlines.

In this chapter, we shall understand what exactly are outlines in CSS; their most common purpose on websites; how are they different from borders in CSS; the outline property, and its constituent individual properties (just like for border); and much more.

Outlines represent an extremely important concept for CSS developers to know and understand since all websites use it in some way, as we shall find out in this chapter.

What are outlines?

Let's start by defining what an outline is in CSS:

An outline defines a stroke around an element, without affecting its dimensions.

Because it also defines a stroke, an outline is similar to a border in CSS. However, they aren't the exact same ideas, per se, as highlighted below:

  • An outline does NOT affect the dimensions of an element whereas a border does.
  • An outline does NOT necessarily have to be rectangular whereas a border does.
  • An outline can NOT be different on different sides whereas a border can (recall border-left, border-top, etc.).

Because of its similarity to a border, defining an outline on an element is similar to defining a border. Let's see how to do so.

The outline property

Just like we have the border property for setting borders in CSS, we have outline for outlines. Quite simple, right?

Here's its syntax:

outline: <width><style><color>;
  • <width> specifies the width of the outline. It can be an absolute length, like 1px, or a keyword, like thick. The default is medium (i.e. 3px).
  • <style> defines the style of the outline. For example, dotted produces a dotted outline, solid produces a solid one, and so on. The default is none (i.e. no outline).
  • <color> defines the outline's color. The default is auto (typically giving a black colored outline).
Akin to border, the outline property is a shorthand for individual properties governing the different aspects of an outline. We'll discover these properties in the next section.

Let's now take a quick example of defining an outline.

HTML
<p>This is a paragraph.</p>
CSS
p {
   outline: 2px solid red;
}

This is a paragraph.

Visually, as you'd agree, there isn't much difference between a border and an outline when the thickness is small. However, the moment we increase the thickness, the difference starts to become apparent.

We'll see this distinction in detail later on in this chapter.

Individual outline properties

As stated earlier, outline is a shorthand for defining an outline in CSS in one go (just like border).

If we, however, want to configure only a particular aspect of an outline, we can use the individual properties outline-width, outline-style, and outline-color.

In fact, the value of outline itself resolves down to these individual properties (by the CSS engine).

So, for instance, this outline definition,

CSS
p {
   outline: 3px dotted blue;
}

is equivalent to the following:

CSS
p {
   outline-width: 3px;
   outline-style: dotted;
   outline-color: blue;
}

This is a paragraph.

Let's consider a more practical application of these individual properties.

Suppose we have a <p> element with an initial outline around it, colored light grey, as shown below.

CSS
p {
   outline: 3px solid lightgrey;
}

This is a paragraph.

Now, we want to give a hover style to this <p> which should change the outline's color to red; the rest of the aspects of the outline should remain the same.

How to do so?

Well, one option is to redefine the outline completely using outline: (Hover over it to see the color change.)

CSS
p:hover {
   outline: 3px solid red;
}

This is a paragraph.

But clearly, this is overkill. We ought to repeat the two other aspects of the outline, i.e. its style and color. There must be a better way.

And there surely is — just use outline-color:

CSS
p:hover {
   outline-color: red;
}

Pretty elegant.

Outlines and accessibility

At the start of this chapter, we learnt that outlines were introduced in the CSS2 Specification, as people felt their need. But what exactly does this mean?

What is the significance of outlines for websites? Why do we need them?

This section is all that we need to address these questions.

First things first, outlines were introduced mainly to improve the accessibility of a web page. How? Let's find out...

What is accessibility?

If you're unfamiliar with it, accessibility refers to the capacity of a web page to be used by as many users on as many devices in as many ways as possible.

For example, if a webpage can be used equally well on mobile phones as on desktop devices, without a mouse or a keyboard, then it's considered to be highly accessible.

Essentially accessibility measures how many people can access a given web page.

Typically, we are accustomed to navigating across webpages using the mouse, barely using the keyboard for navigation, obviously except for when entering data into input fields.

This doesn't, however, mean that everyone ought to navigate across a webpage using a mouse; we can also use a keyboard to navigate across a web page and open up links, click on buttons, submit forms, etc.

And this leads to an important accessibility concern.

If someone is navigating through a webpage using the keyboard, how to visually give the cue as to which particular element is currently in focus?

This is something that outline was meant to solve. Giving an outline around the currently focused element is a convention in modern-day websites.

Browsers tend to give outlines, by default, around interactive elements (hyperlinks, buttons, inputs, etc) unless we override them using our own CSS styles.

Why couldn't other CSS properties be used here?

This is a good question. A really good one. Fortunately, the answer to it isn't that difficult to reason about.

Basically, to distinguish the currently focused element from the rest of the elements on a webpage, we need to style it differently. The style characteristics that we can play with here are color, shape, and/or size of the element, or add something else near the element.

The problem with the rest of the style characteristics is that we, more often than not, can't use the same styling for all interactive elements on the page.

For example, if the border color of an input element is changed upon focus, we might not be able to do the same for a hyperlink (as it might not have a border applied in the first place). Similarly, if we change the color for a hyperlink, we might not be able to do the same for an input element because an empty input would then show nothing.

Another issue with using borders is that they modify the dimensions of an element and so, if used for styling the focused element, they would modify the layout of the web page — something to be wary of!

In short, while other CSS properties can certainly be used to visually emphasize the focused element, they require more careful designing and tweaking based on the type of the underlying element.

Or as they say, these properties do NOT offer us a one-size-fits-all solution in almost all cases. Outlines, however, do.

As stated before, using outlines to visually emphasize the focused element on a web page is a convention. And best of all, we don't need to worry about tweaking them for different elements.

They don't affect the element's dimensions, don't interfere with the rest of its styles, are superbly easy to work with — what else could we ask for.

Consider the following illustration of a link in focus in Chrome (by virtue of navigating to it via the keyboard):

Default outline around a focused hyperlink in Chrome
Default outline around a focused hyperlink in Chrome

We don't need to do anything special to get this styling implemented; it's already there in the default user agent stylesheet of Chrome (and of other browsers as well).

What we can do is to override it, for instance, by changing the outline's color, its style, or its width, or just throw away the outline completely (something which should be done with caution).

For example, below we change the outline color of the focused element from black to blue with the help of the :focus-visible pseudo selector:

CSS
:focus-visible {
   outline-color: blue;
}

Open up the example page linked below and navigate across the page using the Tab key on your keyboard. As you do so, you'll notice how the currently focused element changes as you continuously press the Tab key.

Live Example

To remove the outline completely from all focused elements, we simply ought to set the following:

CSS
:focus-visible {
   outline: none;
}

Apply this style with caution!

In the following illustration, notice the same hyperlink as shown above, still having active focus on the web page:

No outline around a focused hyperlink in Chrome
No outline around a focused hyperlink in Chrome

Can you tell in any way that the hyperlink is currently focused?

No, right? That's the problem.

Removing the outline style should NOT be done at any cost unless we have something else to distinguish the currently focused element on a web page.

If you wish to remove outlines from interactive elements, make sure to add something else to give the visual cue when they receive focus or otherwise you risk substantially reducing your website's accessibility.

The outline-offset property

Besides the three properties — outline-width, outline-style, and outline-color — that we discussed above, there is yet another property related to configuring outlines in CSS. It's outline-offset.

The very first thing to note regarding outline-offset is that it is NOT included in the shorthand outline property (as we saw earlier in this chapter). It's a completely separate property, meant to position an outline.

The official specification for outline expands upon this nicely:

The shorthand purposefully omits the outline-offset property, which determines the position rather than the appearance of the outline, so that it can cascade independently, as well as for backwards compatibility reasons.

Wait what? Position an outline? What does that mean?

As per the name, outline-offset specifies the distance between an element's border box and its outlines (often referred to as the distance by which the outline is offset from the border box).

By modulating the distance where an offset is drawn, outline-offset certainly modifies the position of that offset.

Initially, outline-offset is 0, that is, the offset is drawn right after the border box. But using outline-offset, we can alter this behavior.

Let's consider an example.

Below we have an element with a background color applied (to make it clear as to where its border box ends) and an outline offset by its intial offset value, i.e. 0:

CSS
p {
   background-color: pink;
   outline: 3px solid green;
}

This is a paragraph.

From here, let's dial up the offset using outline-offset and see the change:

CSS
p {
   background-color: pink;
   outline: 3px solid green;
outline-offset: 5px;
}

This is a paragraph.

Notice the whitespace here between the green outline and the pink box of the paragraph — this distance corresponds to outline-offset.

Surprisingly enough, outline-offset can also be negative, as illustrated below:

CSS
p {
   background-color: pink;
   outline: 3px solid green;
outline-offset: -7px;
}

This is a paragraph.

But obviously, negative offsets aren't that commonly used.

Differences between outlines and borders

The outline and border properties work the same way, however, they aren't the same. In this section, we shall understand the difference between both of them.

Outlines do NOT affect an element's dimensions

Perhaps, of all the differences between outlines and borders, the most obvious is that outlines don't affect the dimensions (and therefore the layout) of an element.

This is a direct opposite of the case with borders, which do affect an element's dimensions.

Consider the following example:

CSS
p {
   outline: 15px solid red;
}

This is a paragraph.

Notice how the outline is running outwards from the element, without affecting its dimensions.

For even better understanding, following is a comparison of this outline with a similarly styled border:

CSS
p {
   border: 15px solid red;
}

This is a paragraph.

The border is within the bounds of the width available to the element, i.e. it isn't exceeding past that width.

For this reason, outlines might overlap with one another, as illustrated up next:

This is paragraph 1.

This is paragraph 2.

The first paragraph has a 15px orange outline while the second one has a 15px red one. Both these outlines, because of their sheer widths, intersect with one another because they originate outwards from the elements' border boxes.

Had we used a border here, there would've been no such intersection.

Outlines do NOT have to be rectangular

A border has to be rectangular in shape (with additional rounded edges if there is a specification of border-radius), around the bounding box of an element. However, outlines don't have to follow this rule.

Consider the following example:

HTML
<p>
   <span>This is <sup>sup text</sup> paired with <em>large italic text</em>.</span>
</p>
CSS
span {
   outline: 2px solid red;
}

sup {
   display: inline-block;
}

em {
   display: inline-block;
   font-size: 1.5em;
}

We have a piece of text inside a <span> comprised of a <sup> that goes above the top bound of the normal text flow (since it's a superscript) and an <em> which is large in size to exceed both the top and bottom bounds.

The display: inline-block style is necessary in the code above in order to get the <sup> and <em> elements take up their own space.

The outline around the <span> looks something like this:

This is sup text paired with large italic text.

It follow the bounding box of each of the constituent elements of the <span>. Contrast this with a border specification, as illustrated below:

This is sup text paired with large italic text.

As is evident, border follows the normal text flow of the <span> without getting affected by the constituent elements' layout.

Outlines can NOT be defined for given sides

Unlike borders in CSS, for which we have properties corresponding to different sides — border-top, border-right, and so on — there isn't any such thing for outlines.

An outline in CSS is wholistic, that is, it can only be applied in its entirety.

Spread the word

Think that the content was awesome? Share it with your friends!

Join the community

Can't understand something related to the content? Get help from the community.

Open Discord

 Go to home Explore more courses