Back to Home

What's new in level 4 CSS selectors?

css · css4

What's new in level 4 CSS selectors?

This is a translation of the post " What's new in CSS selectors 4 ". It seemed interesting to me, and I decided to transfer it to Habrahabr. PS This is my first translation, do not judge strictly, and if you see any shortcomings and errors - please write in a personal letter, I will try to correct the errors. Further, according to the author.

Please keep in mind that this article describes a draft specification for January 2015, which means that the information in this article is subject to change without notice.

The fourth level CSS selectors are the next generation of the CSS specification, the latest version of which was released in 2011 , having been in draft mode for several years.

So what awaits us new?


SELECTOR PROFILES

CSS selectors are now divided into two groups: fast and full . Quick selectors are those that are suitable for a dynamic CSS engine. The full group of selectors is suitable for use in those situations in which fast data sampling is not so important, for example, when using them through document.querySelector .

Selectors are used in a wide variety of contexts, which vary greatly in speed characteristics. Unfortunately, some powerful selectors are too slow to use in performance-sensitive contexts. To solve this problem, two selector specification profiles were created. [a source]


: HAS

: has is one of the most interesting parts of the fourth-level CSS selector specification, but it comes with an important warning, which will be discussed later. This selector allows you to specify which objects should be present inside the specified element in order for this rule to work in relation to it.

This opens up great scope for new options for specifying the required elements. For an example, we can select all sections in which headings are present:

// Любая секция, в которой есть заголовок
section:has(h1, h2, h3, h4, h5, h6)


Another option: the developer can select all paragraphs that contain images, or, conversely, only elements that are not images are present.

// Выберем параграфы, которые не имеют чего-либо, не являющегося изображением
p
  :has(img)             // имеет изображение
  :not(:has(:not(img))) // не имеет внутри чего-либо, не являющегося изображением


You can even select those elements that have a certain number of descendants (in this example, five):

// Сайдбар с пятью элементами внутри
div.sidebar
    :has(*:nth-child(5))       // Имеет пять потомков
    :not(:has(*:nth-child(6))) // Но не шестого


Caution: at the moment, the: has selector is not considered fast, which means that it may not be available for use in style files. But, since no one has yet implemented this selector in practice, the question of its performance remains open. If browser developers can make its implementation quick, it is possible that it will be available for use as one of the main tools.

In a previous version of the specification, this section was marked with an exclamation mark and was called “selector subject selection” - it had a different syntax, which has now been removed.

: MATCHES

: matches is a standardization of: moz-any and: webkit-any, which has been present in browser prefixes for some time . This allows the style author to combine similar rules. For example, this may be useful for combining SCSS / SASS-generated output, such as this:

  body > .layout > .body > .content .post p a.image.standard:first-child:nth-last-child(4) ~ a.image.standard, 
  body > .layout > .body > .content .post p a.image.standard:first-child:nth-last-child(4), 
  body > .layout > .body > .content .post li a.image.standard:first-child:nth-last-child(4) ~ a.image.standard, 
  body > .layout > .body > .content .post li a.image.standard:first-child:nth-last-child(4), 
  body > .layout > .body > .content .page p a.image.standard:first-child:nth-last-child(4) ~ a.image.standard, 
  body > .layout > .body > .content .page p a.image.standard:first-child:nth-last-child(4), 
  body > .layout > .body > .content .page li a.image.standard:first-child:nth-last-child(4) ~ a.image.standard, 
  body > .layout > .body > .content .page li a.image.standard:first-child:nth-last-child(4) {
       ....
}

in a slightly more verifiable option:
body > .layout > .body > .content 
    :matches(.post, .page) 
    :matches(p, li) 
    :matches(a.image.standard:first-child:nth-last-child(4), 
             a.image.standard:first-child:nth-last-child(4) ~ a.image.standard), 
       ....
}

There are warnings on its performance on the Mozilla documentation pages above. Since this selector will now become the standard, we hope to see the results of work on its performance that will help make it easy.

: NTH-CHILD (AN + B [OF S])

While: nth-of-type has existed since the turn of the millennium , fourth-level CSS selectors add the ability to perform filtering based on a selector:
div :nth-child(2 of .widget)

The S selector is used to determine the index, and it is independent of the selector to the left of the pseudo-class. As written in the specification, if you know the element type in advance, the: nth-of-type selector can be converted to: nth-child (... of S), like this:
img:nth-of-type(2) => :nth-child(2 of img)

The difference between this selector and: nth-of-type is small, but it is important. For: nth-of-type, each element - whether you specified a selector for it or not - has an implicit index for itself among its brothers with the same tag name. Expression: nth-child (n of S) creates a new counter every time you use a new selector.

This creates potential for possible bugs in the new selectors. Since the selector inside the: nth-child pseudo-class does not depend on the selector to the left of it, you can accidentally skip part of your query if you specify everything in the left selector, but forget to specify everything you need inside: nth-child. For instance:
tr:nth-child(2n of [disabled])

This rule may not work as you expect from it if other non-tr elements have the attribute “disabled”.

In a previous version of the specification, this feature was called as a selector: nth-match.

: NOT ()

At a time when you used some time: not, now you can list several arguments inside it to save a few bytes and enter:
// Эквивалентно следующему:
//    :not(h1):not(h2):not(h3)...
:not(h1, h2, h3, h4, h5, h6)


SHOCK COMBINATOR (>>)

The descendant combinator is present in CSS from the very beginning as a space (), but now it has an explicit version:
// Эквивалентно следующему:
//    p img { ... }
p >> img { ... }

The reason for adding this rule is to organize a bridge between the direct descendant (>) and the operator for the transparent DOM (>>>).

COLUMN COMBINATOR (||) AND: NTH-COLUMN

Fourth-level CSS selectors add column operations that allow style designers to more easily change the design of specific columns in a table. The current approach to setting styles for tables requires the use of: nth-child, which does not always match table columns when using colspan attributes .

When using the new column combinator, you can style the table cells that are in the same column as the specified col element:

// Следующий пример делает ячейки C, E и G жёлтыми
// (пример взят из спецификации CSS-селекторов 4-й версии)
col.selected || td {
  background: yellow;
  color: white;
  font-weight: bold;
}
A B C
D E
F G

Alternatively, the author can use: nth-column and: nth-last-column to style cells. In any case, if a cell spans multiple columns, this selector will affect any of them.

: PLACEHOLDER-SHOWN

One small addition to the selector language is: placeholder-shown. It corresponds to an input element if and only if it displays text from its placeholder attribute.

: ANY-LINK

: any-link is another small addition. It is declared to match any of the: link or: visited properties.
// Эквивалентно следующему:
//    a:link, a:visited { ... } 
a:any-link { ... }


CONCLUSIONS

Fourth-level CSS selectors are still under development, but right now there are useful selectors that we have reviewed, and which can offer developers new models and tools for setting styles. There are other new selectors in the specification that were not considered by me (the author of the article - approx. Per.) In this article, related to accessibility, data validation, as well as scoped attributes in style elements.

If you have a desire to play around with these selectors, you should wait for browser developers to catch up with the specification, or use some early implementations. : matches is available as: moz-any and: webkit-any, and nightly builds of WebKit have early support for: nth-child selectors via flag activation .

Since this is a draft, pseudo-class names may change without notice. Follow the specifications for more details.

Read Next