В современной спецификации CSS функции sibling-count() и sibling-index() открыли отличные возможности для адаптации компонентов. Дочерний элемент теперь может самостоятельно узнать, сколько у него соседей, и настроить оформление. Однако здесь верстальщики упираются в фундаментальное ограничение: CSS-каскад строго однонаправлен. Стили передаются сверху вниз — от предков к потомкам, но никогда обратно.
Родительский контейнер остается слеп к количеству собственных детей. Он не может получить числовую переменную с числом потомков, чтобы подставить ее в математические функции calc(), sqrt() или тригонометрические формулы. Официальное предложение children-count() пока находится на стадии ранних обсуждений в W3C.
Фронтенд-исследователь Темани Афиф (Temani Afif) нашел остроумный обходной путь. Он продемонстрировал, как анимации по шкале прокрутки (CSS Scroll-Driven Animations) позволяют «пробить» каскад снизу вверх и передать счетчик детей в числовую переменную --n на родителе без единой строчки JavaScript.
Механика трюка: фиктивный маркер и проброс через timeline-scope
В основе решения лежит связка трех механизмов:
- Маркер ширины: внутрь контейнера помещается служебный тег
<n></n>. Его ширина рассчитывается через число соседей:width: calc((sibling-count() - 1) * 1px). Если в контейнере 16 карточек, ширина маркера составит ровно 16 пикселей. - Экспорт шкалы времени (
timeline-scope): маркер объявляет горизонтальную шкалу видимостиview-timeline: --n x. Родительский блок указываетtimeline-scope: --n, что поднимает область видимости шкалы на уровень родителя и позволяет привязать анимацию контейнера к геометрии потомка. - Конвертация геометрии в число: на родителе запускается анимация переменной
--nот 1000 до 0. Диапазонanimation-range: exit calc(100% - 1000px) exitкалибрует прогресс строго по ширине маркера в пикселях. В итоге переменная--nна контейнере получает точное целочисленное значение количества дочерних блоков.
<div class="container">
<div class="card">Элемент 1</div>
<div class="card">Элемент 2</div>
<div class="card">Элемент 3</div>
<div class="card">Элемент 4</div>
<!-- Служебный маркер для передачи счетчика родителю -->
<n></n>
</div>
/* Родительский контейнер */
.container {
position: relative;
overflow: hidden;
/* Поднимаем область видимости шкалы времени маркера */
timeline-scope: --n;
animation: --n-anim linear both;
animation-timeline: --n;
animation-range: exit calc(100% - 1000px) exit;
/* Динамическая адаптивная сетка на основе квадратного корня */
display: grid;
grid-template-columns: repeat(round(up, sqrt(var(--n))), 1fr);
gap: 16px;
}
/* Служебный элемент-маркер */
.container > n {
position: absolute;
left: 0;
width: calc((sibling-count() - 1) * 1px);
view-timeline: --n x;
}
/* Анимация преобразует сдвиг границы в числовую переменную */
@keyframes --n-anim {
0% { --n: 1000; }
to { --n: 0; }
}
Адаптивные квадратные сетки на чистом CSS с помощью sqrt()
Получив переменную --n, контейнер обретает динамические возможности:
- Выражение
grid-template-columns: repeat(round(up, sqrt(var(--n))), 1fr)автоматически вычисляет число колонок. - Если в контейнере 9 элементов, сетка перестроится в 3x3. Если элементов 16 — в 4x4, а для 12 элементов раскладка примет вид 4x3. Все это происходит реактивно при изменении разметки без JavaScript и хрупких медиавыражений.
Значение --n можно использовать и для отображения счетчиков в интерфейсе:
/* Вывод общего числа элементов через CSS-счетчики */
.container::before {
counter-reset: total-items var(--n);
content: "Всего карточек в секции: " counter(total-items);
grid-column: 1 / -1;
font-weight: 600;
}
Границы применимости: смелый эксперимент против продакшен-стандартов
Инженеру важно помнить об ограничениях приема. Связка timeline-scope и sibling-count() стабильно работает только в браузерах на Chromium (Google Chrome и Microsoft Edge 125+), а в Safari и Firefox находится в разработке.
Кроме того, метод требует position: relative и overflow: hidden. В продакшене до стандартизации children-count() надежнее использовать строку JS (container.childElementCount). Тем не менее эксперимент Темани Афифа доказывает: возможности современной веб-платформы выходят далеко за привычные рамки верстки.
