Стоило нам только немного привыкнуть к новым возможностям, которые нам подарил CSS 3, как на горизонте появился новый термин — CSS 4. Значит ли это, что CSS 3 уже не самый новый и крутой стандарт? Давайте разберемся.

На самом деле, нет никакого CSS 4, равно как нет и CSS 3. В отличие от CSS 2.1, который был описан в одном большом документе, CSS 3 поделен на несколько документов, называемых «модулями». Каждый модуль добавляет новые возможности либо расширяет функционал, описанный ранее. Каждый такой модуль имеет свой статус стабильности и может развиваться независимо от других модулей. Несколько модулей уже имеют 4 версию, именно их и имеют ввиду, когда говорят про CSS 4.

Недавно W3C опубликовали черновой вариант модуля селекторов 4 уровня. Большинство новых селекторов в модуле 4 уровня — псевдо-классы. Давайте, познакомимся с некоторыми из них поближе.

Псевдо-классы :matches и :not

Начнем с логических псевдо-классов. Первый из них, :matches, позволяет нам группировать похожие селекторы в один. Например, имеем такой фрагмент CSS:

.blog .articles .article.featured .icon:before, 
.blog .articles .article.new .icon:before { 
    /* стили */ 
}

Используя псевдо-класс :matches, мы можем сократить его до одного селектора:

.blog .articles .article:matches(.featured, .new) .icon:before { 
    /* стили */ 
}

Второй логический псевдо-класс, :not, появился в уровне 3 модуля селекторов, но в уровне 4 стал еще более мощным. Теперь ему можно передавать несколько селекторов в качестве параметров:

.modal:not(.hidden, .visuallyhidden) { 
    position: fixed; 
}

Такой селектор выберет все элементы с классом .modal и без классов .hidden и .visuallyhidden.

Псевдо-классы :any-link и :local-link

Эти два псевдо-класса упрощают оформление ссылок. Первый, :any-link, просто объединяет псевдо-классы :link и :visited в один. А вот второй псевдо-класс гораздо более интересный. Он позволяет, к примеру, иначе оформить внешние ссылки:

:not(:local-link(0)) { 
    color: blue; 
}

Теперь все внешние ссылки будут синими. Параметр в скобках определяет, сколько уровней пути URL должны быть проверены на предмет совпадений. Звучит страшно, но на самом деле все очень просто. Допустим, у нас есть следующий фрагмент CSS:

:local-link(0) { 
    color: red; 
} 
:local-link(1) { 
    color: green; 
} 
:local-link(2) { 
    color: blue; 
} 
:local-link(3) { 
    color: orange; 
}

Допустим, адрес страницы http://example.com/blog/archive/2012/. Ссылки, начинающиеся на http://example.com/, будут красными, все ссылки, начинающиеся на http://example.com/blog/ будут зелеными, ссылки на http://example.com/blog/archive/ будут синими и так далее.

Псевдо-класс :indeterminate

Псевдо-класс :indeterminate позволяет выбрать чекбоксы и радио-кнопки, которые имеют неопределенное состояние, а точнее не являются выбранными и не выбранными:

Три состояния чек-бокса в ОС Windows 7 Три состояния чекбокса в ОС Windows 7
input[type="checkbox"]:indeterminate { 
    background: #ccc; 
}

Кроме этого, неопределенное состояние может иметь элемент progress, процент завершения процесса которого не известен.

Псевдо-классы :nth-match и :nth-last-match

Эти псевдо-классы представляют собой объединение функционала псевдо-классов :nth-child и :matches. Допустим, у нас есть список ссылок. Некоторые из этих ссылок имеют класс .active. Мы же хотим выбрать только четные ссылки из всех активных ссылок этого списка:

li a:nth-match(even of .active) { 
    color: red; 
}

Псевдо класс :nth-last-match аналогичен селектору :nth-match, но начинает искать элементы с конца документа.

Селектор родительского элемента

Самое мощное нововведение модуля селекторов 4 уровня. До нынешнего момента все селекторы позволяли фильтровать элементы по их свойствам и свойствам их родительских элементов. Селектор родительского элемента позволяет фильтровать элементы по свойствам их дочерних элементов. Это открывает перед дизайнером невероятно широкие возможности.

Хочу вместо подчеркивания сделать ссылкам с изображениями в качестве содержимого границы:

a! img { 
    border: 1px solid blue; 
    text-decoration: none; 
}

Хочу во вложенном меню подчеркнуть родительский пункт текущего пункта меню:

nav ul li! li.active { 
    text-decoration: underline; 
}

Хочу чтобы ширина галереи менялась в зависимости от количества фотографий в ней:

.gallery .photo { 
    float: left; 
    width: 150px; 
} 
.gallery! .photo:nth-child(3) { 
    /* три фотки в ряд */ 
    width: 450px; 
} 
.gallery! .photo:nth-child(4) { 
    /* по две фотки в два ряда */ 
    width: 300px; 
} 
.gallery! .photo:nth-child(6) { 
    /* по три фотки в два ряда */ 
    width: 450px; 
}

Хочу менять фон документа при наведении на логотип:

body! a.logo:hover { 
    background-image: url(fancy-pattern.png); 
}

Все возможные варианты применения этого селектора перечислить невозможно.

Селектор по значению атрибута

Этот селектор позволяет выбрать элементы по атрибуту id, указанному в атрибуте другого элемента. Например, я хочу во время отладки подсвечивать элемент input, к которому относится элемент label, на который я навел мышь:

label:hover /for/ input { 
    box-shadow: 0 0 10px 3px orange; 
}

Состояние документа

На данный момент спецификация селекторов 4 уровня находится в разработке, синтаксис селекторов еще может измениться. Но изучение документа в текущем его состоянии позволяет понять, в какую сторону будет развиваться CSS и чего можно ожидать от него в будущем.