Difference Between Blank and Empty Pseudo-Classes

difference between blank and empty pseudo-classes

The :blank pseudo-class builds upon the :empty pseudo-class. Like
:empty, :blank will select elements that contain nothing at all, or
contain only an HTML comment. But, :blank will also select elements
that include whitespace, which :empty will not
.

css-tricks :blank

Also, From the W3c Working Draft on selectors level 4:

The :blank pseudo-class is identical to the :empty pseudo-class,
except that it additionally excludes characters affected by whitespace
processing [CSS3TEXT] when determining whether an element is empty.

Example:

For example, the following element matches :blank, but not :empty,
because it contains at least one linebreak, and possibly other
whitespace:

<p> 
</p>

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

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>

CSS selector for empty or whitespace

Lots of people missing the point of this question, which I've addressed in the following exposition, but for those just looking for the answer, I'm mirroring the last paragraph here:

Selectors 4 now redefines :empty to include elements that contain only whitespace. This was originally proposed as a separate pseudo-class :blank but was recently retconned into :empty after it was determined that it was safe to do so without too many sites depending on the original behavior. Browsers will need to update their implementations of :empty in order to conform to Selectors 4. If you need to support older browsers, you will have to go through the hassle of marking elements containing only whitespace or pruning the whitespace before or after the fact.


While the question depicts a <p> element containing a handful of regular space characters, which seems like an oversight, it is far more common to see markup where elements contain only whitespace in the form of indentation and blank lines, such as:

<ul class="items">
<li class="item">
<div>
<!-- Some complex structure of elements -->
</div>
</li>
<li class="item">
</li> <!-- Empty, except for a single line break and
indentation preceding the end tag -->
</ul>

Some elements, like <li> in the above example as well as <p>, have optional end tags, which can cause unintended side effects in DOM processing as well in the presence of inter-element whitespace. For example, the following two <ul> elements don't produce equivalent node trees, in particular the first one does not result in a li:empty in Selectors level 3:

li:empty::before { content: '(empty)'; font-style: italic; color: #999; }
<ul>

<li>

</ul>

<ul>

<li></li>

</ul>

Why do I need an empty `content` property on an ::after pseudo-element?

You cannot style generated content without defining what that content should be. If you don’t really need any content, just an extra “invisible element” to style, you can set it to the empty string (content: '') and just style that.

It’s easy to confirm this yourself: http://jsfiddle.net/mathias/YRm5V/

By the way, the snippet you posted is the micro clearfix hack, which is explained here: http://nicolasgallagher.com/micro-clearfix-hack/

As for your second question, you’ll need an HTML5 shiv (small piece of JavaScript) to make <nav> stylable in some older browsers.

Is there an css trick to emulate CSS4 :blank selector?

Selectors don't match text nodes, so there is no way to emulate either :blank, or :empty using a selector.

Taken literally, .parent:not(:scope > *) represents any .parent element that is not a child of the :scope element, whatever that scoping root may be. If the selector is not scoped, then it is equivalent to .parent:not(:root > *), or if it appears in a scoped stylesheet, generally it means any such element that is not a sibling of the style element representing this scoped stylesheet.

I suspect you mean something like .parent:not(:has(> *)), which will match .parent elements that don't have element children, but it doesn't take into account their text contents, again for the same reason I mentioned.

The good news is, while you still have to wait for vendors to get around to implementing this new feature, instead of implementing it in a separate :blank pseudo they're considering modifying the functionality of :empty instead, provided it doesn't break too many sites. See this answer.

How to check if an element matches the :empty pseudo-class in pure JS?

function isEmpty (el) {
if (!el.hasChildNodes()) return true;

for (var node = el.firstChild; node = node.nextSibling;) {
var type = node.nodeType;
if (type === 1 && !isEmpty(node) || // another element
type === 3 && node.nodeValue) { // text node
return false;
}
}
return true;
}

As per the CSS spec, this will return true if the given element has no non-empty child nodes. Long-awaited JSFiddle demo available.

CSS Selector for adding content through :after / :before when HTML element is missing

This won't be possible without the functionality of the :blank pseudo-class, I'm afraid.1

There are only two possible places you can insert a ::before pseudo-element in your scenario: in the ul, or in a li. Since you want to insert the generated content only when no li elements are present, that leaves you only with ul.

Although ::before and ::after are inserted before and after an element's descendant elements respectively, you can't target them relative to those descendant elements with a sibling combinator, and pseudo-elements currently do not support structural pseudo-classes. Which means, in other words, you won't be able to say "prevent ul::before from generating content in the presence of one or more li elements", nor can you apply the :only-child pseudo-class to ul::before.

In a situation where one can use :empty, it's as simple as

ul:empty::before { content: 'abc'; }

but since you cannot use :empty for the reasons you have given, if you really cannot prevent the whitespace from being generated (e.g. if the content is coming from a WYSIWYG editor or some other transformation that may result in leftover whitespace) you'll have to add a class to any ul elements with no children.


1 A recent revision to selectors-4 proposes subsuming the functionality of :blank into :empty instead, but that likewise is new and requires the cooperation of implementers.

:empty pseudoclass when adding dynamic content

The fiddle you provided works for me with FF10 and IE9. It only fails in Chrome (18+)

Not sure why this happens, as the quirksmode page works in Chrome as well..

For the force-discard it seems to be do-able by setting almost any css property with code..

example at http://jsfiddle.net/gaby/YprUV/9/

Update

Ok, i found this Chrome bug report that is about :empty selector misbehaving when used with display:none

It is marked as fixed, but perhaps we should re-oopen it..

Here is a test that does not use display:none (it just changes the background color) and it works just fine.. http://jsfiddle.net/YprUV/11/



Related Topics



Leave a reply



Submit