CSS :empty selector: styling elements with no content

CSS :empty selector: styling elements with no content

Most of the time we style elements that contain something. What about an element with no children and no text? Easy, you can use the :empty selector.

html
<p> </p>
<!-- Pas à cause de l'espace blanc -->

<p></p>
<!-- Vide car pas d'espace blanc -->
css
p::before {
font-family: 'FontAwesome';
content: 'f240';
}

p:empty::before {
content: 'f244';
}

p {
color: silver;
}

p:empty {
color: red;
}

What counts as empty?

When I first ran into this, there was some confusion about what this selector counts as empty. Let us stick to MDN’s definition here:

The :empty CSS pseudo-class represents any element that has no children. Children can be either element nodes or text (including whitespace). Comments, processing instructions and CSS content do not affect whether an element is considered empty.

:empty

As long as there is no whitespace, the element is empty.

html
<p></p>

A comment in between still counts as an empty element. As long as there is no whitespace.

html
<p><!-- comment --></p>

Not :empty

Whitespace counts as not empty. Even a new line is whitespace, so: not empty! I am labouring the point because I made the same mistake.

html
<p> </p>

<p>
<!-- comment -->
</p>

Having a child element also counts as not empty

html
<p><span></span></p>

Whitespace in the future spec

The good news is that in Selectors Level 4, whitespace will count as empty. That will make it behave like :-moz-only-whitespace. In other words, this will be considered empty:

html
<p> </p>

BUT do not rely on it yet. No browser supports it at the moment.

Examples using :empty

Let us look at a few real uses of :empty.

Using :empty for a form error message

This is the example that made me discover :empty. I wanted an icon in front of my error message. The trouble was that the icon showed up even when there was no error message. No problem: I can simply use :empty to add the icon only when there is a message to show.

CSS

css
.error:before {
color: red;
content: '274c '; /* ❌ icon */
}

HTML

html
<!-- Pas de message d'erreur -->
<div class="error"></div>

<!-- Oui, un message d'erreur -->
<div class="error">Email manquant</div>

Output

Without empty

❌ Email manquant

With :empty

❌ Email manquant

Using :empty in alerts

Here is another example, using :empty to hide the empty state.

css
.alert {
background: pink;
padding: 10px;
}
.alert:empty {
display: none;
}

HTML

html
<div class="alert"></div>
<div class="alert">Message d'alerte</div>

Output

Without :empty

Message d’alerte

With :empty

Message d’alerte

Browser support

Support is actually very good. Every browser back to Internet Explorer 9 handles it

CSS

Damien Flandrin Web developer since 2010, creator of Gekkode and Email Impact. Every article is tested on a real project before publication. Contact
Newsletter

New tests, tutorials and projects, by e-mail.

Reproducible tests, versioned code, dated results. Never any spam.