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
CSS Set Width to Fill % of Remaining Area
Difference Between "Margin-Left", and "Left" (Or "Margin-Right", and "Right")
Are There Any CSS Standards That I Should Follow While Writing My First Stylesheet
Bootstrap: How to Collapse Navbar Earlier
How to Create Pure CSS 3-Dimensional Spheres
How to Specify Font Attributes for All Elements on an HTML Web Page
How to Make an Iframe Resizable
Youtube Video Embedded Via Iframe Ignoring Z-Index
How to Make My Font Bold Using CSS
How to Make the New Long Shadow Trend with CSS
How to Find Unused CSS in a Website
"Text-Decoration" and the ":After" Pseudo-Element
How to Set Cache for CSS/Js File
How to Reset CSS3 *-Transform: Translate(…)
Differencebetween * and *|* in CSS