CSS3-селекторы – фундаментально полезная вещь.
Даже если вы почему-то (старый IE?) не пользуетесь ими в CSS, есть много фреймворков для их кросс-браузерного использования CSS3 из JavaScript.
Поэтому эти селекторы необходимо знать.
Основных видов селекторов всего несколько:
- * – любые элементы.
- div – элементы с таким тегом.
- #id – элемент с данным id.
- .class – элементы с таким классом.
- [name="value"] – селекторы на атрибут (см. далее).
- :visited – «псевдоклассы», остальные разные условия на элемент (см. далее).
Селекторы можно комбинировать, записывая последовательно, без пробела:
- .c1.c2 – элементы одновременно с двумя классами c1 и c2
- a#id.c1.c2:visited – элемент a с данным id, классами c1 и c2, и псевдоклассом visited
В CSS3 предусмотрено четыре вида отношений между элементами.
Самые известные вы наверняка знаете:
- div p – элементы p, являющиеся потомками div.
- div > p – только непосредственные потомки
Есть и два более редких:
- div ~ p – правые соседи: все p на том же уровне вложенности, которые идут после div.
- div + p – первый правый сосед: p на том же уровне вложенности, который идёт сразу после div (если есть).
Посмотрим их на примере HTML:
<h3>Балтославянские языки</h3>
<ol id="languages">
...Вложенный OL/LI список языков...
</ol>
CSS-селекторы:
/*+ no-beautify */
#languages li {
color: brown; /* потомки #languages, подходящие под селектор LI */
}
#languages > li {
color: black; /* первый уровень детей #languages подходящих под LI */
}
#e-slavic { font-style: italic; }
#e-slavic ~ li { /* правые соседи #e-slavic с селектором LI */
color: red;
}
#latvian {
font-style: italic;
}
#latvian * { /* потомки #latvian, подходяще под * (т.е. любые) */
font-style: normal;
}
#latvian + li { /* первый правый сосед #latvian с селектором LI */
color: green;
}
Результат:
При выборе элемента можно указать его место среди соседей.
Список псевдоклассов для этого:
- :first-child – первый потомок своего родителя.
- :last-child – последний потомок своего родителя.
- :only-child – единственный потомок своего родителя, соседних элементов нет.
- :nth-child(a) – потомок номер a своего родителя, например :nth-child(2) – второй потомок. Нумерация начинается с 1.
- :nth-child(an+b) – расширение предыдущего селектора через указание номера потомка формулой, где a,b – константы, а под n подразумевается любое целое число.
Этот псевдокласс будет фильтровать все элементы, которые попадают под формулу при каком-либо n. Например: -:nth-child(2n) даст элементы номер 2, 4, 6…, то есть чётные.
- :nth-child(2n+1) даст элементы номер 1, 3…, то есть нечётные.
- :nth-child(3n+2) даст элементы номер 2, 5, 8 и так далее.
Пример использования для выделения в списке:
/*+ hide="CSS к примеру выше" no-beautify */
li:nth-child(2n) { /* чётные */
background: #eee;
}
li:nth-child(3) { /* 3-ий потомок */
color: red;
}
- :nth-last-child(a), :nth-last-child(an+b) – то же самое, но отсчёт начинается с конца, например :nth-last-child(2) – второй элемент с конца.
Фильтр по месту среди соседей с тем же тегом
Есть аналогичные псевдоклассы, которые учитывают не всех соседей, а только с тем же тегом:
- :first-of-type
- :last-of-type
- :only-of-type
- :nth-of-type
- :nth-last-of-type
Они имеют в точности тот же смысл, что и обычные :first-child, :last-child и так далее, но во время подсчёта игнорируют элементы с другими тегами, чем тот, к которому применяется фильтр.
Пример использования для раскраски списка DT «через один» и предпоследнего DD:
/*+ hide="CSS к примеру выше" no-beautify */
dt:nth-of-type(2n) {
/* чётные dt (соседи с другими тегами игнорируются) */
background: #eee;
}
dd:nth-last-of-type(2) {
/* второй dd снизу */
color: red;
}
Как видим, селектор dt:nth-of-type(2n) выбрал каждый второй элемент dt, причём другие элементы (dd) в подсчётах не участвовали.
На атрибут целиком:
- [attr] – атрибут установлен,
- [attr="val"] – атрибут равен val.
На начало атрибута:
- [attr^="val"] – атрибут начинается с val, например "value".
- [attr|="val"] – атрибут равен val или начинается с val-, например равен "val-1".
На содержание:
- [attr*="val"] – атрибут содержит подстроку val, например равен "myvalue".
- [attr~="val"] – атрибут содержит val как одно из значений через пробел.
Например: [attr~="delete"] верно для "edit delete" и неверно для "undelete" или "no-delete".
На конец атрибута:
- [attr$="val"] – атрибут заканчивается на val, например равен "myval".
- :not(селектор) – все, кроме подходящих под селектор.
- :focus – в фокусе.
- :hover – под мышью.
- :empty – без детей (даже без текстовых).
- :checked, :disabled, :enabled – состояния INPUT.
- :target – этот фильтр сработает для элемента, ID которого совпадает с анкором #... текущего URL.
Например, если на странице есть элемент с id="intro", то правило :target { color: red } подсветит его в том случае, если текущий URL имеет вид http://...#intro.
Псевдоэлементы ::before, ::after
«Псевдоэлементы» – различные вспомогательные элементы, которые браузер записывает или может записать в документ.
При помощи псевдоэлементов ::before и ::after можно добавлять содержимое в начало и конец элемента:
<style>
li::before {
content: " [[ ";
}
li::after {
content: " ]] ";
}
</style>
Обратите внимание: содержимое добавляется <b>внутрь</b> LI.
<ul>
<li>Первый элемент</li>
<li>Второй элемент</li>
</ul>
Псевдоэлементы ::before/::after добавили содержимое в начало и конец каждого LI.
:before или ::before?
Когда-то все браузеры реализовали эти псевдоэлементы с одним двоеточием: :after/:before.
Стандарт с тех пор изменился и сейчас все, кроме IE8, понимают также современную запись с двумя двоеточиями. А для IE8 нужно по-прежнему одно.
Поэтому если вам важна поддержка IE8, то имеет смысл использовать одно двоеточие.