The Brand New CSS4 Selectors Specification

January 30, 2012 at 6:00 pm By

CSS4 Already?!

Yeah, the CSS4 specification is already in the early stages of being written (for selectors, anyway). I must stress just how work in progress this is, in the sense that some of this stuff might not make the final cut, while more stuff may be added. It will however give you an idea of what you can expect some of this to turn up in the real CSS4 specification. Most of these ideas are probably the basis of what the W3C is aiming for in the CSS4 Selectors Specification.

Not and Matches


These are perhaps my two favourite additions. You may have already heard of the :not() selector, something that turned up in the CSS3 specification. The :matches() selector will undoubtedly be new to you.

Not

E:not(s1, s2) an E element that does not match either compound selector s1 or compound selector s2

In the CSS4 Specification it says :not() can be used for both selectors and pseudo classes. It will not work with :after or :before, but everything else works great. So lets say you want to apply to everything except links. You might do this:

*|*:not(:link):not(:visited) {
    /* Some CSS */
}

Useful, eh? In a large project this is certainly going to cut down code. Which leads us on to matches(). As a note, *|* is a general “apply to everything” rule. Basically it’ll apply the CSS to all elements.

Matches

E:matches(s1, s2) an E element that matches compound selector s1 and/or compound selector s2

matches() literally matches any pseudo class. You cannot really mix matches() and not. The specification clearly mentions that you cannot do :matches(:not( ... )). That’d be kind of silly anyway! Here’s an example in which you could apply some stuff to all hovered items:

*|*:matches(:hover) {
     /* Some CSS */
}

A variety of direct selectors


There are a few new selectors that are mentioned in the specification, and they all have their various uses.

Reference Combinators

E /foo/ F an F element ID-referenced by an E element’s foo attribute

This one is a bit complicated, and took me a while to wrap my head around! Lets say you have this in your form, for example:


  <label for="name">Your Name</label>
  <input id="name" type="text" />

The for attribute, by definition should be the same as in the input ID. In a matter of sense, these two elements are connected. This pseudo class lets you target connected elements. So if you wanted to target the input when the label is hovered over you could do this. I’m sure you could apply this to other elements that are connected.

label:hover /for/ input {
    /* CSS goes here */
}

Targeting parents (with CSS!)

E! > F an E element parent of an F element

This was one of my favourites. In CSS the last thing you write is generally what you’re targeting. Let me give you an example:

div a {

}

Anyone who has touched CSS before knows that we’re targeting all anchors in divs, right? With this selector we can use the same syntax, but target the div. Now that might sound a bit useless. If you wanted to do that, you’d just remove the a and it’d target the div directly, right? Well, this in effect lets you do what people have wanted to do with CSS for a long time, which is target a parent of a child. There comes a time when you wish you could do this:

ul li:hover < ul { /* Trying to target parent. This doesn't work */

}

Now with CSS4, one could do this:

ul! li:hover {

}

Now the parent is selected when an li inside it is hovered over. The sheer opportunity this adds to what CSS can do is outstanding, and it’s definitely one of the finer thought out CSS elements. Note that other specifications mention targeting parents as $E > F instead of an exclamation mark.

Any Variation of Characters

E[foo=”bar” i] an E element whose foo attribute value is exactly equal to any (ASCII-range) case-permutation of bar

This is pretty boring compared to selecting parent classes! Anyway, if you did something like this:

</pre>
<div class="foo"></div>
<div class="Foo"></div>
<div class="fOO"></div>
<pre>

(for some reason) and wanted to target all of the divs, you could use this selector to do that! All you’d have to do is this:

div[class='foo' i] {

}

That little i means that the case isn’t taken into account!

Even More Pseudo Classes


A lot of this has to do with columns and the new match() selector.

Match Pseudo Types

E:nth-match(n) an E element, the n-th sibling matching selector
E:nth-last-match(n) an E element, the n-th sibling matching selector, counting from the last one

As you’d might expect, :match() by itself is a slightly boring element. It can’t really do much. So CSS4 have thrown in a few nth-type selectors, so you can select a particular number. For example, you might want to select every 4th element from the start, so you’d do div:nth-match(4n). Then again you might want to select just the 4th element on a page, so you’d do div:nth-match(4). The other one is nth-last-match(), which instead of counting from the start of the page, starts counting from the end.

Columns

E:column(selector) an E element that represents a cell in a grid/table belonging to a column represented by an element that matches selector
E:nth-column(n) an E element that represents a cell belonging to the nth column in a grid/table
E:nth-last-column(n) an E element that represents a cell belonging to the nth column in a grid/table, counting from the last one

Columns aren’t just for tables anymore! So in preparation for the CSS3 specification being finished, the W3C has added a lot of column selectors, in particular for grids. We actually covered the Multi-Column CSS3 Specification here. The column(selector) may select a column with particular characteristics, while the nth-column() picks a column counting from the start, and the nth-last-column() picks a column counting from the end (the opposite of nth-column).

Language and Links

E:lang(fr, en) an element of type E in either language “fr” or language “en” (the document language specifies how language is determined)
E:local-link an E element being the source anchor of a hyperlink of which the target is the current document
E:local-link(0) an E element being the source anchor of a hyperlink of which the target is within the current domain

The language element has been around since CSS2 (I believe), so it’s not really anything new. It uses the knowledge of semantics throughout the document to apply different styles to things that you define in your HTML as a certain language. Quite useful if you own a multinational website or something similar.

The :local-link selectors are going to be super useful, especially when it comes to making navigation. In the past we’d have to use a separate CSS class and apply it to the current page item in the navigation, through PHP or manually adding it into the HTML. With :local-link we can target all links on the current page which link to the current page. Lets say you want to style a menu item that links to the current page. You’d just do this:

#nav:local-link {
     box-shadow: 0px 0px 10px rgba(0,0,0,0.4);
}

Pretty easy huh? This is taken a step further by being able to select particular levels in the URL. So for example:

#nav:local-link(0) {

}

That’ll style URLs linking to the core URL (in our case http://www.html5canvastutorials.com/blog/

If your current URL was, for example, http://www.html5canvastutorials.com/blog/2011/03/25/name/ then..

  • :local-link(0) would style URLs linking to http://www.html5canvastutorials.com/blog/
  • :local-link(1) would style URLs linking to http://www.html5canvastutorials.com/blog/2011/
  • :local-link(2) would style URLs linking to http://www.html5canvastutorials.com/blog/2011/03/
  • :local-link(3) would style URLs linking to http://www.html5canvastutorials.com/blog/2011/03/25/
  • and :local-link(4) would style URLs linking to http://www.html5canvastutorials.com/blog/2011/03/25/name/

Manipulating Time!

E:current an E element that is currently presented in a time-dimensional canvas
E:current(s) an E element that is the deepest :current element that matches selector s
E:past an E element that is in the past in a time-dimensional canvas
E:future an E element that is in the future in a time-dimensional canvas

As cool as that sounds, CSS does not yet let you manipulate the time-space continuum on any scale (CSS5?). What these elements do is let you manipulate things that are happening in real time. For example, highlighting a paragraph as its being read out (Using the CSS3 Speech Spec), or giving us more ways to modify an HTML5 video with subtitles, and perhaps more when the CSS4 specification is done.

Usability (Part of CSS3UI)

E:indeterminate a user interface element E that is in an indeterminate state (neither checked nor unchecked)
E:default The default selection
E:in-range and E:out-of-range In and out of range (perhaps to do with form range elements
E:required and E:optional Required and optional (so required could be in red or have an asterisk after them
E:read-only and E:read-write For elements that can’t be edited, and elements which can

These are all UI elements. There isn’t much to explain really! They largely apply to forms at the minute, but in the future there could be more UI elements included in the HTML specification, in which case these would be more useful. They target inputs and form elements based on their current state. They actually appeared in the CSS3 specification, but I imagine they will be refined and added to more in the CSS4 specification.

Summary

The CSS4 specification in its current form is already bringing a lot of what web developers have wanted for a long time to the proverbial web designer table. We can only hope in the future as this is continually refined browsers will take up the mantle and implement some of these features (particularly targeting parents!). I honestly can’t wait, what are your thoughts?