Полезные псевдо-селекторы

Есть много малоизвестных псевдоселекторов CSS, используя которые можно писать более чистый HTML. Они не только позволяют уменьшить количество классов в нем, но и в некоторых случаях упрощают или вовсе упраздняют логику, которая определяет нужно ли присваивать элементу определённый класс (например, когда есть только один такой элемент, атрибут содержит определённую строку, и т.д.). Использование псевдоселекторов часто позволяет уменьшить количество обращений к DOM, что улучшает производительность.

Я выделю те псевдоселекторы, которые встречаются не часто, но могут быть полезны в некоторых ситуациях. Я упущу селекторы вроде :first-child(), :last-child(), :nth-child(), :nth-last-child(), :before и :after, которые заслуживают упоминания, но уже хорошо известны.

:not() и :matches()

Недавно в спецификацию были добавлены псевдокласс отрицания :not() и псевдокласс соответствия :matches(). :matches, в отличии от :not(), пока не очень хорошо поддерживается браузерами.

Синтаксис:

E:matches(s1, s2)
/* элемент E с селектором s1 и/или селектором s2 */

Лично я считаю что :not — это одно из наилучших дополнений в CSS. Ему можно найти множество применений, особенно в сочетании с другими псевдоселекторами вроде :first-child или :last-child (например, когда нужно добавить отступ/границу для всех элементов кроме первого или последнего).

Синтаксис:

E:not(s1, s2)
/* элемент E, который не содержит селектор s1 или селектор s2 */

Пример:

li:not(:first-child) { }

:empty и :only-child()

Они входят в список структурных псевдоклассов, однако именно эти два почему-то менее популярны, хоть и довольно полезны.

Псевдокласс only-child() пригодится когда нужно прописать больший/меньший отступ/границу для тех элементов, которые содержат только один дочерний элемент, или же вы можете уменьшить размер шрифта если элемент содержит несколько дочерних элементов.

Синтаксис:

E:only-child()
/* элемент E, единственный дочерний элемент для своего контейнера */

Пример:

.items li { margin: 5px 0; font-size: 1.2em; }
.items li:only-child { margin: 0; font-size: 1.5em; }

По сути этот селектор эквивалентен elem:last-child():first-child().

Синтаксис:

E:empty
/* элемент E, который не содержит дочерних элементов (в том числе текстовых узлов) */

Учтите, что даже переход на новую строку считается текстовым узлом, помните об этом в процессе проектирования структуры страницы.

Пример:

.items-container:empty { background-image: url('./path/to/no-items-bg.png'); }

Больше о них и о других можно прочитать в разделе псевдоклассы с древовидной структурой.

:local-link

Псевдокласс :local-link дает возможность стилизировать ссылки, которые ведут на страницы с тем же доменом что и текущая и отделить их от внешних ссылок.

Синтаксис:

:local-link
/* соответствует ссылке на текущем домене */
:local-link(1)
/* соответствует ссылке на текущем домене до первого слеша (пример: galjot.si/) */
:local-link(2)
/* так же как и предыдущий пример, только до второго слеша */
:local-link(n)
/* так же как и предыдущий пример, только до n-ного слеша */

Это позволяет обойтись без лишнего класса в HTML когда нужно стилизировать внутренние ссылки.

Кроме :local-link есть другие широко известные псевдоклассы для ссылок, например :link (ссылка, которая ещё не была открыта) и :visited (ссылка, по которой уже был осуществлен переход), которые хотелось бы видеть на веб-сайтах чаще, особенно на веб-сайтах с преимущественно текстовым содержанием (где они пришлись бы очень кстати), хотя это и спорный момент ввиду возможности скомпрометировать историю пользователя используя селектор :visited.

С целью защиты информации, браузеры жёстко ограничивают перечень стилей, которые можно применить для элемента с псевдоклассом :visited: color, background-color, border-color, outline-color, column-rule-color, fill и stroke. Источник: Защита информации и селектор :visited.

Если вы считаете что защита информации — это здорово, взгляните на следующий код (написанный
@krofdrakula):

Псевдоклассы состояния, которые зависят от пользовательского интерфейса

Следующие псевдо-селекторы делятся на две категории, псевдоклассы ввода и псевдоклассы действия пользователя.

Примеры:

input[type="checkbox"]:checked { }
input:disabled { }

Перечисленные выше псевдоклассы очень пригодятся при разработке пользовательского интерфейса приложений, которые предусматривают ввод данных. Их функции понятны без объяснений, но не все из них подтверждены и одобрены спецификацией (некоторые имеют статус черновика), проверить их текущий статус можно тут.

Распознавание по подстроке

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

Синтаксис:

E[foo^="bar"]
/* элемент E, у которого значение атрибута foo начинается со строки «bar» */

Пример:

a[href^="http://twitter.com"] { }
a[href^="mailto:"]

Синтаксис:

E[foo$="bar"]
/* элемент E, у которого значение атрибута foo заканчивается строкой «bar» */

Пример:

a[href$='.pdf'] { }
a[href$='.doc'] { }
a[href$='.xls'] { }
a[href$='.rss'] { }

Синтаксис:

E[foo*="bar"]
/* элемент E, у которого значение атрибута foo содержит подстроку «bar» */

Пример:

p[class*='post'] { }

:first-line, :first-letter

Этот селектор немного отличается от описанных выше, но если его использовать с умом, он может очень пригодиться при проектировании внешнего вида контента и поможет улучшить его эстетические качества. Приём выделения первой буквы или строки применяется в дизайне печатных изданий уже много лет, взгляните на эти чудесные слайды. Вам также стоит ознакомится со статьей Джона Тена (Jon Tan) под названием «12 примеров типографики абзацев», написанной еще в 2008, в которой описано как можно получить красивые эффекты полагаясь исключительно на селекторы.

Также вас может заинтересовать «Буквица: история применения и передовой опыт современности в CSS», целая статья от Лауры Франц (Laura Franz), посвященная буквице.

:lang

В разных культурах значение цветов может отличаться, так что теперь с помощью селектора :lang можно менять стиль соответственно. Псевдокласс :lang() принимает в качестве аргумента список из одного или больше языков с запятой-разделителем.

Пример:

html:lang(de)

Больше информации о языковом псевдоклассе :lang().

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