Avatar of Matt DeCamp
Matt DeCamp on

The CSS :empty pseudo-class selects any element that does not contain children for a given selector.

/* Changes the background color of every empty section element */
section:empty {
  background-color: tomato;

If we were to run that code on a page, the CSS would look for a <section> element that contains no content between the tags. That might look something like this:

  <p>I have content</p>

  <p>I have content, too!</p>

<section> // HIGHLIGHT
  <!-- No content, just an HTML comment. 🎺 -->

What makes an element “empty”?

An element with nothing between its tags is empty.


That includes if an element contains a code comment.

<div><!--I'm still empty, even with this comment. --></div>

And if the CSS for the element has generated content — as from a pseudo-element like ::before or ::after — it is also still considered empty.

div::before {
  content: "Yep, still empty!;"

Elements with children (aka “non-empty” elements)

An element is said to have “children” if it contains another element node, text or even textual white space in between its tags. The elements in the following code are considered “non-empty” ones.

  <h1>I'm a child of this article element.</h1>

<p>This text is considered a child.</p>

<!-- Even whitespace between tags qualifies this element as "non-empty" -->
<h1>   </h1>

But be careful! Code editors may create unwanted white space, making an otherwise empty element a non-empty one.

  <!-- The white space in this element makes it a "non-empty" element -->

It now acts like :-moz-only-whitespaces

:empty was updated to behave like Mozilla’s prefixed :moz-only-whitespace pseudo-class in the Selectors Level 4 specification.  Like :empty:moz-only-whitespace selects empty elements. The difference is that :moz-only-whitespace also selects elements that only contain textual white space. The spec explains it incredibly well:

In Level 2 and Level 3 of Selectors, :empty did not match elements that contained only white space. This was changed so that that—given white space is largely collapsible in HTML and is therefore used for source code formatting, and especially because elements with omitted end tags are likely to absorb such white space into their DOM text contents—elements which authors perceive of as empty can be selected by this selector, as they expect.

So, yeah. This change is more likely to make :empty behave the way we expect, so that even when there are certain elements (e.g. <br>) or white space from formatting inside of an element, they won’t prevent an element from being considered empty.

However, there is currently no browser support for this change.

It’s not great for form validation

You’d think it would be! But if we try to apply :empty to an <input> and hope to make it red to show the user it needs to be completed, that input will always be red.

Why is that? It’s because :empty searches for empty container content, but inputs are considered empty elements even though content can be typed into them.


Empty nav item

In this example, an li element in the navigation is removed when it has no content. Click the button to toggle the empty state for the third navigation item.

Empty API field

Here the :empty pseudo-selector helps us display a direction to the user in order to load a joke into the same field.

Browser support

Android ChromeAndroid FirefoxAndroid BrowseriOS SafariOpera Mobile
Source: caniuse

Support for matching elements with whitespace

Android ChromeAndroid FirefoxAndroid BrowseriOS SafariOpera Mobile
Source: caniuse

More information