:empty and :blank with comment inside
Asked Answered
R

3

6

I am using :empty and :blank. They work fine, but I have a case where AngularJS is injecting comments inside a div, and those will not work anymore. Is there something I can do to make :empty and :blank work with comments?

Roth answered 11/9, 2016 at 10:25 Comment(1)
Wanna mention that together with comment there is one space.Roth
S
1

This issue also happens with angular, these are placeholders for not visible elements (ex: ngIf...)

strating with CSS 4, :empty starts ignoring comments... https://drafts.csswg.org/selectors-4/#the-empty-pseudo

comments, processing instructions, and other nodes must not affect whether an element is considered empty or not.

as a workaround, for now, since :has support is growing (as of writing available everywhere except Mozilla behind a flag), you can do something like:

:not(:has(*)) {
  display: none;
}

NOTE: this works as long as you don't have stray text inside the element. ex:

<div class="container">
text
</div>

here .container:not(:has(*)) is matched, however

<div class="container">
<span>text</span>
</div>

here .container:not(:has(*)) is not matched

Steady answered 19/9, 2023 at 3:57 Comment(0)
I
0

There are few things that you can do... try to have a look at: https://docs.angularjs.org/guide/production paying attention to the $compileProvider.debugInfoEnabled(false);...

Generally is not a good idea the use of :empty (or something else) pseudoselector with the goal of selecting empty elements because that selectors are sensible to everything, whitespace included. There is an example:

div {
  width: 30px;
  height: 30px;
  background: cyan;
  margin: 5px;
}

div:empty { display: none; }
<div>

</div>
<div> </div>

<!-- just this -->
<div></div>

EDITED

a possible workaround could be creating a custom directive that does this for you, but, of course, it should be manually added to the elements where you want to know if they are empty or not. Here is an example:

angular
  .module('test', [])
  .directive('emptyClass', function() {
    return function postLink(iScope, iElement, iAttrs) {
      
      function updateOnChanges() {
        var classname = iAttrs.emptyClass;
        
        var hasContent = iElement.children().length > 0 ||
            iElement.text().trim().length > 0;
        
        if(hasContent) {
          return iElement.removeClass(classname);
        }
        
        return iElement.addClass(classname);
      }
      
      iElement[0].addEventListener(
        "DOMSubtreeModified", updateOnChanges, false
      );
      updateOnChanges();
    }
  })
;
.is-empty { background: cyan; display: block; min-height: 20px; margin: 10px; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<section ng-app="test">
  <h1 empty-class="is-empty">  </h1>
  <h1 empty-class="is-empty"></h1>

  <h1 empty-class="is-empty">
    <!-- ng-if: "oh Yeah" -->
  </h1>
  
  <h1 empty-class="is-empty"> Hello World </h1>
  <h1 empty-class="is-empty"><span>Hello World</span></h1>
</section>
Inoculation answered 11/9, 2016 at 10:38 Comment(6)
$compileProvider will hide the information, but comments are still displayed :(Roth
yes, as I said, there are few things that you can do... this is how angular 1x was made.Inoculation
hmm, can I use ng-cloak to add a class to the div, instead of commenting it out?Roth
probably a custom directive could be the best idea, have a look on my last edits.Inoculation
That works fine, even though there are some small issues, thanks a lot.Roth
what issues you found?Inoculation
P
-1

angular
  .module('test', [])
  .directive('emptyClass', function() {
    return function postLink(iScope, iElement, iAttrs) {
      
      function updateOnChanges() {
        var classname = iAttrs.emptyClass;
        
        var hasContent = iElement.children().length > 0 ||
            iElement.text().trim().length > 0;
        
        if(hasContent) {
          return iElement.removeClass(classname);
        }
        
        return iElement.addClass(classname);
      }
      
      iElement[0].addEventListener(
        "DOMSubtreeModified", updateOnChanges, false
      );
      updateOnChanges();
    }
  })
;
.is-empty { background: cyan; display: block; min-height: 20px; margin: 10px; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<section ng-app="test">
  <h1 empty-class="is-empty">  </h1>
  <h1 empty-class="is-empty"></h1>

  <h1 empty-class="is-empty">
    <!-- ng-if: "oh Yeah" -->
  </h1>
  
  <h1 empty-class="is-empty"> Hello World </h1>
  <h1 empty-class="is-empty"><span>Hello World</span></h1>
</section>
Ploch answered 25/9 at 6:42 Comment(1)
Please explain how this wall-of-code actually solves the issue. Code-only answers are not good answersBryantbryanty

© 2022 - 2024 — McMap. All rights reserved.