:empty doesn't work if there's blank spaces?
Asked Answered
R

6

6

Trying to find a pseudo class that'll target a <div> like this:

<div class="nav-previous">
                            </div>

I've tried :blank and :empty but neither can detect it. Is it just not possible to do?

https://jsfiddle.net/q3o1y74k/3/

Rammish answered 19/3, 2018 at 17:9 Comment(0)
S
1

As the others mentioned, this isn't possible with CSS yet. You can check to see if there's only whitespace with JavaScript however. Here's a simple JS only solution, "empty" divs that match are blue, while divs that have text are red. Updated to add an empty class to the empty divs, which would allow you to target them easily with the selector .empty in your CSS.

The JS only "empty" comparison would look like this:

if(element.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "") == "")

And if you're using jQuery it would be a bit easier:

if( $.trim( $(element).text() ) == "" ){

var navs = document.querySelectorAll(".nav-previous");
for( i=0; i < navs.length; i++ ){
  if(navs[i].innerHTML.replace(/^\s*/, "").replace(/\s*$/, "") == "") {
    navs[i].style.background = 'blue';
    navs[i].classList.add( 'empty' );
  } else {
    navs[i].style.background = 'red';
  }
}
.nav-previous {
 padding: 10px;
 border: 1px solid #000;
}

.nav-previous.empty {
  border: 5px solid green;
}
<div class="nav-previous">
                            </div>
<div class="nav-previous">Not Empty </div>
Select answered 19/3, 2018 at 17:27 Comment(0)
M
2

:empty alone is enough.

By the current Selectors Level 4 specification, :empty can match elements that only contain text nodes that only contain whitespace as well as completely empty ones. It’s just there aren’t many that support it as per the current specification.

The :empty pseudo-class represents an element that has no children except, optionally, document white space characters.

From the MDN:

Note: In Selectors Level 4, the :empty pseudo-class was changed to act like :-moz-only-whitespace, but no browser currently supports this yet.

The :-moz-only-whitespace CSS pseudo-class matches elements that only contain text nodes that only contain whitespace. (This includes elements with empty text nodes and elements with no child nodes.)

Morez answered 30/5, 2022 at 19:42 Comment(0)
C
1

:empty indeed only works for totally empty elements. Whitespace content means it is not empty, a single space or linebreak is already enough. Only HTML comments are considered to be 'no content'.

For more info see here: https://css-tricks.com/almanac/selectors/e/empty/

The :blank selector is in the works, it will match whitespace, see here: https://css-tricks.com/almanac/selectors/b/blank/. But it seems to have no browser support yet.

Update:
See here for possible solutions to this involving jQuery.

Craniometer answered 19/3, 2018 at 17:14 Comment(1)
I did read up on :blank I just didn't know it wasn't out yet. Is there a javascript solution that works like :blank?Rammish
S
1

The problem with your approach is that your container is not actually empty.

The :empty pseudo-class represents an element that has no children at all. In terms of the document tree, only element nodes and content nodes (such as DOM text nodes, CDATA nodes, and entity references) whose data has a non-zero length must be considered as affecting emptiness;

As you have empty spaces this pseudo class will not do the trick.

The :blank pseudo class should be the right one, because this is its definition:

This blank pseudo-class matches elements that only contain content which consists of whitespace but are not empty.

the problem is that this pseudo class isn't implemented by any browser yet as you can check in the link below. So you will need to wait until it get implemented to be able to use this selector.

This pretty much explains the behavior you are facing

https://css4-selectors.com/selector/css4/blank-pseudo-class/

The best approach here is just to be sure that your div will actually be empty, so your approach will work.

the best that you can do is to define an empty class like this:

.empty{
   display:none;
}

and then add this JS code here, it will append the empty class to your blank items:

(function($){
    $.isBlank = function(html, obj){
        return $.trim(html) === "" || obj.length == 0;
    };

    $('div').each(function() {
        if($.isBlank(
            $(this).html(), 
            $(this).contents().filter(function() {
                return (this.nodeType !== Node.COMMENT_NODE);
            })
        )) {
            $(this).addClass('empty');
        }
    });
})(jQuery);

check it working here,

https://jsfiddle.net/29eup5uw/

Sergo answered 19/3, 2018 at 17:23 Comment(0)
S
1

As the others mentioned, this isn't possible with CSS yet. You can check to see if there's only whitespace with JavaScript however. Here's a simple JS only solution, "empty" divs that match are blue, while divs that have text are red. Updated to add an empty class to the empty divs, which would allow you to target them easily with the selector .empty in your CSS.

The JS only "empty" comparison would look like this:

if(element.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "") == "")

And if you're using jQuery it would be a bit easier:

if( $.trim( $(element).text() ) == "" ){

var navs = document.querySelectorAll(".nav-previous");
for( i=0; i < navs.length; i++ ){
  if(navs[i].innerHTML.replace(/^\s*/, "").replace(/\s*$/, "") == "") {
    navs[i].style.background = 'blue';
    navs[i].classList.add( 'empty' );
  } else {
    navs[i].style.background = 'red';
  }
}
.nav-previous {
 padding: 10px;
 border: 1px solid #000;
}

.nav-previous.empty {
  border: 5px solid green;
}
<div class="nav-previous">
                            </div>
<div class="nav-previous">Not Empty </div>
Select answered 19/3, 2018 at 17:27 Comment(0)
P
1

While not exactly the same, if you can safely assume the output and consider having no child element as your definition of "empty", you can leverage :has() in modern browsers.

div:not(:has(> *)) {
  background: red;
}
<div>
  <!-- This will not be colorized -->
</div>

<div>
  <!-- But this will -->
  <span>Some content</span>
</div>
Proselytize answered 30/4, 2024 at 5:36 Comment(0)
V
0

You just can't without JavaScript/jQuery implementation. :empty selector works with empty tags (so without even any space in them) or with self-closing tags like <input />.

Reference: https://www.w3schools.com/cssref/css_selectors.asp

If you want to use JavaScript implementation, I guess here you will find the answer: How do I check if an HTML element is empty using jQuery?

Vanesavanessa answered 19/3, 2018 at 17:25 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.