{"id":339498,"date":"2021-04-27T10:56:17","date_gmt":"2021-04-27T17:56:17","guid":{"rendered":"https:\/\/css-tricks.com\/?page_id=339498"},"modified":"2021-04-27T12:55:38","modified_gmt":"2021-04-27T19:55:38","slug":"empty","status":"publish","type":"page","link":"https:\/\/css-tricks.com\/almanac\/selectors\/e\/empty\/","title":{"rendered":":empty"},"content":{"rendered":"\n

The CSS :empty<\/code> pseudo-class selects any element that does not contain children for a given selector.<\/p>\n\n\n\n

\/* Changes the background color of every empty section element *\/\nsection:empty {\n  background-color: tomato;\n}<\/code><\/pre>\n\n\n\n

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

<section>\n  <p>I have content<\/p>\n<\/section>\n\n<section>\n  <p>I have content, too!<\/p>\n<\/section>\n\n<section> \/\/ HIGHLIGHT\n  <!-- No content, just an HTML comment. 🎺 -->\n<\/section><\/code><\/pre>\n\n\n

What makes an element \u201cempty\u201d?<\/h3>\n\n\n

An element with nothing between its tags is empty.<\/p>\n\n\n\n

<div><\/div><\/code><\/pre>\n\n\n\n

That includes if an element contains a code comment.<\/p>\n\n\n\n

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

And if the CSS for the element has generated content<\/code><\/a>\u2009\u2014\u2009as from a pseudo-element like ::before<\/code> or ::after<\/code>\u2009\u2014\u2009it is also still considered empty.<\/p>\n\n\n\n

div::before {\n  content: \"Yep, still empty!;\"\n}<\/code><\/pre>\n\n\n

Elements with children (aka \u201cnon-empty\u201d elements)<\/h3>\n\n\n

An element is said to have \u201cchildren\u201d if it contains another element node, text or even textual white space in between its tags. The elements in the following code are considered \u201cnon-empty\u201d ones.<\/p>\n\n\n\n

<article>\n  <h1>I'm a child of this article element.<\/h1>\n<\/article>\n\n<p>This text is considered a child.<\/p>\n\n<!-- Even whitespace between tags qualifies this element as \"non-empty\" -->\n<h1>   <\/h1><\/code><\/pre>\n\n\n\n

But be careful! Code editors may create unwanted white space, making an otherwise empty element a non-empty one.<\/p>\n\n\n\n

<section>\n  <!-- The white space in this element makes it a \"non-empty\" element -->\n<\/section><\/code><\/pre>\n\n\n

It now acts like :-moz-only-whitespace<\/code>s<\/h3>\n\n\n

:empty<\/code> was updated to behave like Mozilla\u2019s prefixed :moz-only-whitespace<\/code><\/a> pseudo-class in the Selectors Level 4 specification<\/a>.  Like :empty<\/code>, :moz-only-whitespace<\/code> selects empty elements. The difference is that :moz-only-whitespace<\/code> also selects elements that only contain textual <\/em>white space. The spec explains it incredibly well:<\/p>\n\n\n\n

In Level 2 and Level 3 of Selectors, :empty<\/code><\/a> did not match elements that contained only white space. This was changed so that that\u2014given 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\u2014elements which authors perceive of as empty can be selected by this selector, as they expect.<\/p><\/blockquote>\n\n\n\n

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

However, there is currently no browser support<\/a> for this change.<\/p>\n\n\n

It\u2019s not great for form validation<\/h3>\n\n\n

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