CSS sibling-index() и sibling-count(): создание адаптивных раскладок без :nth-child

Новые CSS-функции sibling-index() и sibling-count() позволяют создавать адаптивные раскладки, основанные на математических зависимостях между соседними элементами, без использования громоздких правил :nth-child или JavaScript-расчётов. Эти инструменты упрощают код, делают его более поддерживаемым и

CSS sibling-index() и sibling-count(): создание адаптивных раскладок без :nth-child

Новые CSS-функции sibling-index() и sibling-count() позволяют создавать адаптивные раскладки, основанные на математических зависимостях между соседними элементами, без использования громоздких правил :nth-child или JavaScript-расчётов. Эти инструменты упрощают код, делают его более поддерживаемым и открывают новые возможности для динамических интерфейсов. Функции входят в спецификацию CSS Values Level 4 и пока находятся на стадии черновика, но уже доступны в экспериментальных версиях браузеров, таких как Safari Technology Preview и Chrome Canary (с флагом «Experimental Web Platform Features»).

Как работают sibling-index() и sibling-count()

Функция sibling-count() возвращает общее количество соседних элементов (сиблингов) внутри родительского контейнера, включая сам элемент. sibling-index() возвращает порядковый номер элемента среди сиблингов, начиная с 1. Эти функции можно использовать внутри любых CSS-свойств, принимающих числовые значения, таких как width, height, font-size, transform, animation-delay и других. Например, чтобы задать каждому элементу списка ширину, обратно пропорциональную его порядковому номеру, можно написать:

css li { width: calc(100% / sibling-count() sibling-index()); }

Этот код автоматически распределит ширину элементов в зависимости от их количества и позиции, без единого медиа-запроса или :nth-child.

Чем отличается от :nth-child?

Селектор :nth-child позволяет выбирать элементы по их позиции, но не даёт доступа к числовому значению индекса или общего количества в расчётах. Для создания каскадных эффектов, например, увеличения отступа или задержки анимации для каждого последующего элемента, приходится писать отдельные правила для каждого n или использовать препроцессоры. С новыми функциями это делается одной строкой:

css .item { animation-delay: calc(sibling-index() 0.1s); }

Этот код создаёт задержку анимации для каждого элемента, увеличивающуюся на 0.1 секунды, независимо от того, сколько элементов в списке.

Предыстория и контекст

Потребность в таких функциях возникла из-за ограничений CSS при работе с динамическими списками. Разработчикам часто приходится прибегать к JavaScript для расчёта ширины, высоты или задержек на основе количества элементов. Это нарушает принцип разделения контента и представления. В 2020 году в CSS появились функции min(), max() и clamp(), которые позволили делать адаптивные расчёты, но для работы с соседними элементами всё ещё не хватало инструментов. Функции sibling-index() и sibling-count() закрывают этот пробел.

Как это работает под капотом?

Браузер вычисляет sibling-count() на этапе построения DOM, когда известно количество дочерних элементов. sibling-index() определяется порядком элементов в дереве. Важно, что эти функции работают только для элементов, имеющих общего родителя. Если элементы находятся в разных контейнерах, функции вернут некорректные значения.

Практическое применение: каскадные эффекты и адаптивные сетки

Одно из самых эффектных применений — staggered cascade effect, когда элементы появляются с нарастающей задержкой. Раньше для этого требовался JavaScript или препроцессор с циклом. Теперь достаточно одного CSS-правила:

css .card { animation: fadeIn 0.5s ease-out both; animation-delay: calc(sibling-index() 0.1s); }

Другой пример — адаптивная сетка, где ширина колонок зависит от их количества. Если нужно, чтобы при четырёх элементах они занимали по 25%, а при трёх — по 33%, раньше приходилось писать медиа-запросы или использовать flexbox с gap. С новыми функциями:

css .item { width: calc(100% / sibling-count()); }

Это работает для любого количества элементов, от 2 до 10 и более.

Кого затронет и как

Новые функции будут полезны фронтенд-разработчикам, создающим динамические интерфейсы: списки товаров, галереи, таймлайны, аккордеоны. Особенно выиграют проекты, где количество элементов меняется в реальном времени, например, дашборды или ленты новостей. Для разработчиков на React или Vue это означает меньше кода на JS и больше декларативного CSS. В российском контексте, где часто используются самописные CMS с динамическими списками, эти функции упростят создание адаптивных шаблонов без дополнительных скриптов.

Что будет дальше

Функции sibling-index() и sibling-count() пока находятся в статусе черновика, но уже получили поддержку в экспериментальных версиях браузеров. Ожидается, что стабильная реализация появится в течение 2026–2027 годов. Разработчикам стоит начать экспериментировать с ними уже сейчас, чтобы быть готовыми к массовому внедрению. Также стоит следить за возможным появлением смежных функций, таких как parent-count() или child-index(), которые могут расширить возможности CSS-математики.

Итог

sibling-index() и sibling-count() — это мощный шаг в сторону декларативных и адаптивных раскладок. Они позволяют выразить сложные математические зависимости между элементами без единой строчки JavaScript. Если вы работаете с динамическими списками, присмотритесь к этим функциям — они могут серьёзно упростить ваш код и сделать его более производительным.