Эта статья — перевод оригинальной статьи «More control over :nth-child() selections with the of S syntax»
Также я веду телеграм канал «Frontend по‑флотски», где рассказываю про интересные вещи из мира разработки интерфейсов.
Селекторы псевдоклассов :nth-child() и :nth-last-child()
С помощью селектора псевдокласса :nth-child() можно выбирать элементы в DOM по их индексу. Используя микросинтаксис An+B, вы получаете тонкий контроль над тем, какие элементы вы хотите выбрать.
:nth-child(2)
: Выберет второй дочерний элемент.:nth-child(2n)
: Выберет все четные дочерние элементы (2-й, 4-й, 6-й, 8-й и так далее).:nth-child(2n+1)
: Выберет все нечетные дочерние элементы (1-й, 3-й, 5-ый, 7-ой и так далее).:nth-child(5n+1)
: Выберет 1-го (=(5×0)+1), 6-го (=(5×1)+1), 11-го (=(5×2)+1), ребенка.
Чтобы интерактивно увидеть, как логика An+B влияет на выделения, используйте тестер :nth-child.
Но можно сделать более творческий выбор, если опустить параметр A
. Например:
:nth-child(n+3)
: Выберет каждый дочерний элемент, начиная с третьего (3-й, 4-й, 5-й и так далее).:nth-child(-n+5)
: Выберет каждый дочерний элемент до 5-го (1-го, 2-го, 3-го, 4-го, 5-го).
Объедините несколько таких селекторов :nth-child()
, и вы сможете выбирать диапазоны элементов:
:nth-child(n+3):nth-child(-n+5)
: Выберет каждый дочерний элемент от 3-го до 5-го (3-й, 4-й, 5-й).
Используя :nth-last-child()
, вы можете делать подобные селекторы, но вместо того, чтобы начинать считать с начала, вы начинаете считать с конца.
Если вы хотите перейти на новый уровень, вы можете использовать :nth-child() для применения стилей к группе элементов, когда они достигают определенного размера ("Quantity Queries") или стилизовать родительский элемент на основе количества его дочерних элементов.
Предварительная фильтрация с помощью синтаксиса of S
Новое в CSS Selectors Level 4 - возможность опционально передавать список селекторов в :nth-child()
и :nth-last-child()
.
:nth-child(An+B [of S]?)
:nth-last-child(An+B [of S]?)
Когда указано of S, логика An+B применяется только к тем элементам, которые соответствуют заданному списку селекторов S. Это означает, что вы можете предварительно отфильтровать дочерние элементы, прежде чем An+B сделает свое дело.
Примеры
Например, :nth-child(2 of .highlight)
выбирает второй подходящий элемент, имеющий класс .highlight. Другими словами: из всех дочерних элементов с классом .highlight
выберите второй.
Это отличается от .highlight:nth-child(2)
, который выбирает элемент, имеющий класс .highlight
, а также являющийся вторым дочерним элементом.
В демонстрационном примере ниже вы можете увидеть эту разницу:
Элемент, соответствующий
:nth-child(2 of .highlight)
, имеет розовый контур.Элемент, соответствующий
.highlight:nth-child(2)
, имеет зеленый контур.
Обратите внимание, что S
- это список селекторов, что означает, что он принимает несколько селекторов, разделенных запятой. Например, :nth-child(4 of .highlight, .sale)
выбирает четвертый элемент, который является либо .highlight
, либо .sale
из множества дочерних элементов.
В демонстрационном примере ниже элемент, соответствующий :nth-child(4 of .highlight, .sale)
, имеет оранжевый контур.
Зебра, пересмотренный вариант
Классическим примером использования :nth-child()
является создание таблицы с полосками зебры. Это визуальный прием, при котором в каждой строке таблицы чередуются цвета. Обычно это делается следующим образом:
tr:nth-child(even) {
background-color: lightgrey;
}
Хотя это хорошо работает для статических таблиц, это становится проблематичным, когда вы начинаете динамически фильтровать содержимое таблицы. Когда, например, вторая строка становится скрытой, в итоге остаются видимыми первая и третья строки, каждая из которых имеет одинаковый цвет фона.
Чтобы исправить это, мы можем использовать :nth-child(An+B [of S]?)
, исключив скрытые строки из логики An+B
:
tr:nth-child(even of :not([hidden])) {
background-color: lightgrey;
}
Довольно круто, правда?
EvgenichTalagaev
Спасибо за перевод, интересная возможность, но поддержка пока хромает.