
Когда CSS становится проблемой производительности
Как чрезмерное использование селекторов и глубокая вложенность влияют на производительность рендеринга.

Продвинутые селекторы, которые вы, скорее всего, никогда не используете
Современный CSS предлагает богатый набор селекторов, которые выходят далеко за рамки классов, ID и простых вложенных селекторов. Многие из этих продвинутых инструментов могут значительно упростить стили, сократить количество лишней разметки и сделать код более выразительным и поддерживаемым. В этой статье рассматриваются самые мощные (и часто недооценённые) селекторы, которые стоит добавить в свой инструментарий.
:is() — мощная группировкаПсевдокласс :is() позволяет объединять несколько селекторов в один, уменьшая дублирование и повышая читаемость.
/* Без :is() */
main > h2,
main > h3,
main > h4 {
margin-block: 1.5rem 0.75rem;
}
/* С :is() */
main > :is(h2, h3, h4) {
margin-block: 1.5rem 0.75rem;
}Сильно сокращает повторения
Упрощает рефакторинг
Хорошо работает с длинными цепочками селекторов
Совет: :is() не увеличивает специфичность выше самого «сильного» селектора внутри, поэтому безопаснее старых приёмов группировки.
:where() — группировка с нулевой специфичностью:where() похож на :is(), но всегда имеет нулевую специфичность.
:where(article, section, aside) h2 {
font-size: 1.5rem;
margin-block: 1.5rem 1rem;
}Подходит для глобальных значений по умолчанию
Легко переопределяется
Упрощает масштабирование дизайн-систем
Правило: используйте :is() для обычных правил, :where() — для базовых.
:has() — стилизация родителя по дочерним элементам:has() позволяет выбирать элемент, если внутри него есть другой элемент.
.card:has(img) {
border-color: var(--accent);
}.nav-item:has(a[aria-current="page"]) {
background: var(--nav-active-bg);
}Позволяет стилизовать родителя без дополнительных классов
Уменьшает потребность в JavaScript
Упрощает работу с состояниями
li:has(+ li) {
border-bottom: 1px solid #ddd;
}Важно: :has() может быть ресурсоёмким — избегайте слишком сложных условий.
:has()Внутри :has() можно использовать комбинаторы.
label:has(+ input:focus) {
color: var(--accent);
}header:has(+ section.hero) {
margin-bottom: 0;
}Это заменяет многие JS-решения.
:not() — отрицание с расширенными возможностями:not() исключает элементы по условию.
button:not(.btn-primary) {
background: transparent;
}input:not(:disabled, [readonly]) {
cursor: text;
}Уменьшает количество «обратных» классов
Позволяет писать правила «для всех, кроме…»
[type="text"]/* Начинается с */
[class^="icon-"] { }
/* Заканчивается на */
[a$=".pdf"]::after { }
/* Содержит */
[class*="-danger"] { }
/* Содержит слово */
[data-flags~="beta"] { }
/* Языковой код */
[lang|="en"] { }Темизация
Обозначение типов файлов
Работа с BEM-модификаторами
:nth-child() — не только odd/even.card:nth-child(3n) {
border-color: var(--accent);
}.list-item:nth-child(-n + 3) {
font-weight: 600;
}:nth-of-type()
:first-child, :last-child
:only-child
:nth-last-child()
.list-item:nth-last-child(-n + 2) {
color: #777;
}article > p:first-of-type {
font-size: 1.1rem;
}.container > *:last-child {
margin-bottom: 0;
}.card > :only-child {
text-align: center;
}Лучше всего подходят для CMS, блогов и документации.
::marker, ::selection и другие::marker — маркеры списковul.fancy-list li::marker {
color: var(--accent);
}::selection — выделение текста::selection {
background: #222;
color: #fff;
}::file-selector-buttoninput[type="file"]::file-selector-button {
background: var(--accent);
}Позволяют улучшать интерфейс без хака и JS.
:root и дизайн-токены:root {
--color-bg: #0f172a;
--color-accent: #3b82f6;
}html[data-theme="dark"] {
--color-bg: #020617;
}:root — основа для переменных и темизации.
[data-context="danger"]
:is(button, .btn-primary):not([data-variant="ghost"]) {
background: var(--danger);
}.card:has(.card-footer) {
padding-bottom: 1.5rem;
}@media (min-width: 48rem) {
.card:nth-child(3n) {
margin-right: 0;
}
}Комбинации позволяют отказаться от лишнего HTML и JS.
Проверяйте поддержку :has() и новых псевдоэлементов
Не жертвуйте читаемостью ради «умных» трюков
Следите за специфичностью (:is() vs :where())
Избегайте слишком широких селекторов
Документируйте сложные паттерны
Продвинутые селекторы — :is(), :where(), :has(), атрибутные и структурные — позволяют выразить сложную логику в минимальном количестве кода. Они помогают упростить HTML, сократить JavaScript и сделать стили более чистыми и надёжными.
В следующий раз, когда захочется добавить ещё один wrapper или переключать класс через JS, подумайте: возможно, редкий CSS-селектор решит задачу элегантнее и проще.
Давайте обсудим, как я могу помочь воплотить её в жизнь. Готов ответить на вопросы и рассказать о возможных решениях.
Связаться со мной
Как чрезмерное использование селекторов и глубокая вложенность влияют на производительность рендеринга.

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