Style :headings

Styling headings in CSS is about to get much easier. With the new :heading pseudo-class and :heading() function, you can target headings in a cleaner and more flexible way.

This browser does not support :heading!

Unfortunately, this browser does not support this feature. At the moment of writing this article, only Firefox Nightly supported it. In order to test it, follow these steps:

  1. Download and install Firefox Nightly.
  2. Open the browser.
  3. In the address bar, enter about:config.
  4. If a warning pops-up, click on "Continue."
  5. In the search bar, enter "heading" (without the quotes.)
  6. Click on the toggle button, to set its value to true.

Currently, if we want to select all the headings in an HTML document, we can do it by concatenating all the selectors in a single rule:

h1, h2, h3, h4, h5, h6 {
  /* code here */
}

This is clunky and limited. And if we want to select only certain heading levels, we have to write something even messier and clunkier.

There are two new features in CSS that can help with this task:

Let's check each of them separately.

:heading

:heading is a pseudo-class that will select all headings within the scope (by default, the whole document). That means any h1, h2, h3, h4, h5, or h6 tag.

Notice how there are two restrictions:

Here's a quick example:

The following demo is simulated because this browser does not support :heading.
<h1>Page Title</h1>
<h2>Chapter Title</h2>
<p>Some text</p>
<h3>Section title</h3>
:heading {
color: red;
}

Page Title

Chapter Title

Some text

Section title

As mentiond above, :heading is a pseudo-class, and it will have the same specificity weight as a class (0-1-0).

:heading()

:heading() is a pseudo-class function that provides more flexibility than :heading as it takes a list of one or more levels to select. For example, :heading(2, 3) will select all the h2 and h3, but not the h1.

You might ask, "But, Álvaro, why not just use the selector h2, h3? It would be easier and shorter!"

Great question. While a heading level is usually indicated by the number in the tag (h1 is level 1, h2 is level 2, etc.), there are ways reset and update a heading level. For example, using the HTML attributes headingoffset or headingreset (not fully supported either, but that's other story).

Unfortunately, just as elements with role="heading" are not recognized as headings by :heading, using aria-level is also not enough for CSS to recognize a new heading level.

The following demo is simulated because this browser does not support :heading().

<h1>Page Title</h1>
<h2>Chapter Title</h2>
<p>Some text</p>
<h3>Section title</h3>
:heading(2, 3) {
color: blue;
}

Page Title

Chapter Title

Some text

Section title

A trick when using :heading(): the arguments don't have to be strictly numeric. We can use An + B functional notation (e.g., 2n + 1), or keywords like odd and even to select the heading we want. (Note: the demo above does not support the functional notation.)


Bibliography and Links

The new CSS heading pseudo-classes and functions are easy, simple and powerful. They are a convenient and clean way to style headings.

If you want to learn more, visit these sites: