CSS4 – Selectors Level 4



Progress does not stand still, and, following the CSS3, the new CSS4 comes to us, which is developing by the W3C editing team. Historically, the process of development of CSS is independent from the process of development of web-browsers – both are developed in parallel. This has led to the fact that different browsers support different sets of CSS specifications. But back to CSS4. W3C periodically update a working (draft) specification CSS4 and I want to give you first and basic information about what is already included in the specification of CSS selectors level 4.





Quite a plenty of new changes was brought with CSS4. No new pseudo elements was added, it seems that they might be added in other modules in the future. However, in the development of pseudo classes was paid a lot more attention. The following elements were added in CSS4 (at the current moment): logical combinations, elemental and attribute selectors, new pseudo-classes, combinators and grid-structural selectors. The following is high-level overview of them.

Logical Combinations: Negation and Matches-any Pseudo-classes

In CSS3, the negation pseudo-class :not can be applied only to simple selectors, pseudoclasses, tags, identifiers, classes and class selectors parameters. Pseudoelements and such combinations like UL LI or UL > LI was not supported, also we could not include the negation pseudo-class :not in itself. In Level 4, however, :not( ) can now be applied to a list of selectors and complex selectors. Now, no longer will selector lists have to be divided into separated blocks of code for each selector.

p:not(.active, .visible) { color: yellow; }

The same applies for the :matches class – a new pseudo-class that would allow for matching styles to certain elements. You can use the :matches pseudo-class to group selectors together, to have one line of code grouping items for matching.

article:matches(.active, .visible) { background: green; }

Attribute Selectors: Case-sensitivity

Presently, in the CSS4, the case of attributes will no longer have to be case-sensitive with the use of the identifier i before the closing bracket ]. For example, in

[frame=hsides i] { border-style: solid none; }

the ‘hsides’ attribute will be applied to the ‘frame’ whether it is ‘HSIDES’, ‘hsides’, ‘Hsides’ and so on. And this applies even in XML with case-sensitive attribute values. This is useful to avoid prolonged debug.

Linguistic Pseudo-classes

There is another new CSS4 pseudo-class – :dir. As a directionality pseudo-class, it is used in HTML5 to help us determine the directionality of elements, along with other factors such as surrounding text. A :dir(rtl) pseudo-class will give an element a directionality of right-to-left, while a :dir(ltr) will have a opposite directionality: left-to-right. Pay attention that the :dir is not the same thing as [dir=…] attribute selectors, since :dir matches the value as determined by the UA.

New changes occur to linguistic pseudo-classes :lang. Currently, :lang can perform wildcard matching. For instance, :lang(de-DE) matches all of the matching language tags, not just ‘de-DE’ and ‘de-DE-1996’. Wildcard matching on the primary language (or first subtag), is done with an asterisk. For instance, *-CH would match ‘de-CH’, ‘it-CH’, and so on.

CHeck the following example which describes the following: the two following selectors represent an HTML document that is in Belgian French or German. The two next selectors represent q quotations in an arbitrary element in Belgian French or German:

html:lang(fr-be) html:lang(de) :lang(fr-be) > q :lang(de) > q

Location Pseudo-classes

The Location pseudo-classes refer to the visitor’s location on your site (do not confuse it with the geocoding). New changes are coming to location pseudo-classes. One of them is a hyperlink pseudo-class named :any-link in which it stands for any element that is the source anchor of a hyperlink.

The second is the :local-link pseudo-class which styles hyperlinks, depending on the website visitor’s location on the site. This pseudo-class also can differentiate between external and internal links. The :local-link refers to elements that have a source anchor hyperlink whose target is the same as the element’s document URL in non-functional use. In functional use :local-link can be in a hierarchical scheme as follows:

:local-link(0) – represents a link element whose target is in the same origin as the document’s URL

:local-link(1) – represents a link element whose target has the same origin and first path segment

:local-link(2) – represents a link element whose target has the same origin, first, and second path segments

and so on

The :scope pseudo-class stands for elements that are in the reference element set. This is is a set of elements that provide a reference point for selectors to match against, such as that specified by the querySelector() call in [SELECTORS-API2], or the parent element of a scoped <style> element in HTML5.

Several examples:

nav :local-link { text-decoration: none; } a:local-link(0) {...} a:local-link(1) {...}

User Action Pseudo-classes: drag-and-drop pseudo-classes

This drag-and-drop :drop pseudo-class applies to elements defined as areas on the page specified to be ‘drop areas’, or in other words, placements on which a user can drop a dragged element. The functional :drop pseudo-class simply goes beyond the regular :drop function to allow for extra filters:

:drop(active) – drop target is the current drop target for the drag operation. That is, if the user were to release the drag, it would be dropped onto this drop target

:drop(valid) – if the host language has a concept of ‘valid’ and ‘invalid’ drop targets, this only matches if the drop target is valid for the object currently being dragged. Otherwise, it matches all drop targets

:drop(invalid) – if the host language has a concept of ‘valid’ and ‘invalid’ drop targets, this only matches if the drop target is invalid for the object currently being dragged. Otherwise, it matches nothing.

Example:

:valid-drop-target { box-shadow: 0 0 5px yellow; } :active-drop-target { outline: solid red; }

Time-dimensional Pseudo-classes

The time-dimensional pseudo-classes allow for classification of elements within certain timeframes, for example during speech rendering of a document. The :current pseudo-class is for the element or its ancestor that is active at the moment. For instance, a paragraph being read aloud would be highlighted with the following:

:current(p, li, dt, dd) { background: yellow; }

The :past pseudo-class refers to an element specified to happen before a :current element. A :future pseudo-class is to opposite, refers to an element defined to occur after a :current element.

The Input Pseudo-classes

The listed pseudo-classes refer to elements that take user input, such as HTML’s <input> element.

The :enabled and :disabled pseudo-classes

The :enabled pseudo-class represents user interface elements that are in an enabled state; such elements have a corresponding disabled state. Conversely, the :disabled pseudo-class represents user interface elements that are in a disabled state; such elements have a corresponding enabled state.

The mutability pseudo-classes :read-only and :read-write

An element matches :read-write if it is user-alterable, as defined by the host language. Otherwise, it is :read-only.

The placeholder-shown pseudo-class :placeholder-shown

Input elements can sometimes show placeholder text as a hint to the user on what to type in.

The default-option pseudo-class :default

The :default pseudo-class applies to the one or more UI elements that are the default among a set of similar elements. Typically applies to context menu items, buttons and select lists/menus.

The selected-option pseudo-class :checked

Radio and checkbox elements can be toggled by the user. Some menu items are “checked” when the user selects them. When such elements are toggled “on” the :checked pseudo-class applies.

The indeterminate-value pseudo-class :indeterminate

The :indeterminate pseudo-class applies to UI elements whose value is in an indeterminate state.

The validity pseudo-classes: :valid and :invalid

An element is :valid or :invalid when its contents or value is, respectively, valid or invalid with respect to data validity semantics defined by the document language. An element which lacks data validity semantics is neither :valid nor :invalid.

The range pseudo-classes :in-range and :out-of-range

The :in-range and :out-of-range pseudo-classes apply only to elements that have range limitations. An element is :in-range or :out-of-range when the value that the element is bound to is in range or out of range with respect to its range limits as defined by the document language. An element that lacks data range limits or is not a form control is neither :in-range nor :out-of-range.

The optionality pseudo-classes :required and :optional

A form element is :required or :optional if a value for it is, respectively, required or optional before the form it belongs to can be validly submitted. Elements that are not form elements are neither required nor optional.

The user-interaction pseudo-class :user-error

The :user-error pseudo-class represents an input element with incorrect input, but only after the user has significantly interacted with it. The :user-error pseudo-class must match an :invalid, :out-of-range, or empty-but-:required form element between the time the user has attempted to submit the form and before the user has interacted again with the form element. User-agents may allow it to match such elements at other times, as would be appropriate for highlighting an error to the user.

Tree-Structural pseudo-classes

The two existing structural pseudo classes (:empty and :root) were supplemented by the new :blank pseudo-class. It is similar to :empty, except that it also refers to the characters between elements. For instance:

<p> </p>

It could be considered as :blank but not :empty, because of the line break and other possible whitespaces.

Two new structural pseudo classes were added – :nth-match(An+B of <selector>) and :nth-last-match(An+B of <selector>). The :nth-match stands for items with siblings of (An+B-1) that match a certain selector list that comes before it; the :nth-last-match is similar except it refers to a matching selector list after it in the document.

Combinators

This pseudo-class allows targeting of connected elements using A /ATTR/ B, whereas one element is ID-referenced by the ATTR attribute of another element. This follows the same rules as for Attribute Selectors. THe following example shows highlighting an input when the label is hovered on:

label:matches(:hover, :focus) /for/ input, /* association by 'for' attribute */ label:matches(:hover, :focus):not([for]) input { /* association by containment */ box-shadow: yellow 0 0 10px; }

Targeting a Parent

CSS4 let us target a parent element using A! > B, where the A element is the parent of the B element. For example we can target the parent of an element when that element is hovered on. As you know, in a drop down menu when the last li is active, the parent li always loses focus in CSS3. However, with the ability to target the parent, it is possible to give the parent li some certain styles when the child li is active, check the following example:

ul! li:hover { color: blue; }

Grid-Structural Selectors

In CSS3, columns are possible, but it is very difficult to isolate them for styling. CSS4 allows us to do this – an easy method for working with individual columns. Firstly, this is the column combinator ‘||’ which allows for selection of a column that has a specified set of features. The :nth-column(n) allows for styling of certain columns, starting the count from the beginning. In contrary, the :nth-last-column(n) starts the count from the end. Pay attention, that both :nth-column and :nth-last-column can include ‘odd’ and ‘even’ values. Have a look to the following example:

col.selected || td { background: gray; color: white; font-weight: bold; } td:nth-column(1) { text-align: center; }

<table> <col span="2"> <col class="selected"> <tr><td>A <td>B <td>C <tr><td colspan="2">D <td>E <tr><td>F <td colspan="2">G </table>