Как контейнерные запросы; но для застрявших, зависших и переполненных запросов.
Опубликовано: 15 января 2025 г.
Chrome 133 основывается на запросах контейнеров, вводя запросы контейнеров с состоянием прокрутки. Управляемое браузером состояние для закрепленного позиционирования, точек привязки прокрутки и прокручиваемых элементов теперь можно запрашивать и адаптировать из CSS.
Обзор
Прежде чем запрашивать состояние прокрутки, вам нужно будет использовать JavaScript, чтобы понять, застрял ли элемент, защелкнулся или прокручивается. Теперь на пути стандартов появился более эффективный метод получения этой информации и соответствующей адаптации. Также появился новый способ запуска анимации, разблокирующий анимацию, запускаемую прокруткой, из CSS.
Вот обзор запросов состояния, доступных в Chrome 133:
- Состояние зависания :
- Стиль триггера меняется, когда элемент прилипает к краю.
- Зафиксированное состояние :
- Стиль триггера меняется, когда элемент привязывается к оси.
- Прокручиваемое состояние :
- Стиль триггера меняется, когда элемент переполнен.
Хорошая новость заключается в том, что все, что вы узнали из запросов к контейнерам, поможет вам работать с запросами состояния прокрутки.
Существует также неизведанная территория между анимацией, управляемой прокруткой , и запросами контейнера состояния прокрутки; нам нужно поэкспериментировать со временем и контекстом, чтобы определить, какая анимация, управляемая прокруткой, или анимация состояния прокрутки, запускаемая прокруткой, будет лучше. Следующее видео и демонстрация иллюстрируют затруднительное положение; липкая триггерная анимация по сравнению с анимацией, управляемой прокруткой.
Первый запрос состояния прокрутки
Первым шагом является определение контейнера, используя новое значение свойства container-type
. Как и в случае с запросом контейнера, элемент, который вы хотите запросить, — это тот элемент, которому вы указываете container-type
и, при необходимости, container-name
. С помощью запросов состояния прокрутки вы указываете элемент, который привязывается, застревает или имеет container-type: scroll-state
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
}
Второй шаг — выбрать дочерний элемент этого контейнера, который будет реагировать на состояние, поскольку в запросах контейнера это не может быть тот же элемент, который имеет container-type
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
Третий шаг — попробовать. В следующем примере CSS фон будет оформлен в красный цвет, когда элемент .stuck-top
прикрепится к верхнему значению 0
. Благодаря нескольким дополнительным строкам в CSS, которые мы уже написали, и дополнительному содержащему элементу, который передает состояние браузера, наши компоненты гораздо умнее относятся к своему окружению.
Прогрессивное улучшение
Правило @supports
и вложенность позволяют добавлять прогрессивное улучшение или условное использование функций всего за пару дополнительных строк кода:
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
@supports (container-type: scroll-state) {
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
}
Кроме того, не забудьте использовать @media (prefers-reduced-motion: no-preference) {}
для вашего движения, если в конечном итоге вам придется анимировать элементы на странице с помощью запросов состояния прокрутки.
Варианты использования
Застрявший
Возможно, этот раздел следует назвать «Неприятные ситуации»? Это небольшая коллекция сценариев использования закрепленных состояний, а также бонусный раздел идей, которые необходимо реализовать.
@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}
Добавить тень при застревании
Один из наиболее распространенных случаев использования зависшего запроса — это панели навигации, которые хотят добавить box-shadow
при зависании, чтобы они могли казаться плавающими над содержимым, которое они накладывают.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
transition: box-shadow .3s ease;
@container scroll-state(stuck: top) {
box-shadow: var(--shadow-5);
}
}
}
Активировать текущий застрявший заголовок
Другой распространенный сценарий закрепления обратной связи пользовательского интерфейса — выделение застрявшего в данный момент элемента. В списке групп, расположенных в алфавитном порядке, это может быть очень полезно и полезно для опыта.
.sticky-slide {
dt {
container-type: scroll-state;
position: sticky;
inset-block-start: 0;
inset-inline: 0;
> header {
transition:
background .3s ease,
box-shadow .5s ease;
@container scroll-state(stuck: top) {
background: hsl(265 100% 27%);
box-shadow: 0 5px 5px #0003;
}
}
}
}
Вот еще один вариант, в котором заголовки находятся сбоку от элементов списка. Много возможностей!
Переполнение идей
Вот список запоминающихся демонстраций, которые могут вдохновить вас добавить в демо немного остроты или удалить JavaScript с помощью запросов состояния прокрутки. Я предлагаю попробовать создать тот, который вам понравится, это поможет сохранить синтаксис и идеи 😏.
- https://codepen.io/BlogFire/pen/PoGMjaX - вариант липких заметок
- https://codepen.io/mikegolus/pen/jOZzRzw — добавлять тени к таблице, когда они прилипают
- https://codepen.io/MarcRay/pen/PomBeP - панель навигации под заголовком появляется при триггере
- https://codepen.io/kevinpowell/pen/OqKJjK – отображение нижней панели навигации
- https://codepen.io/abhisekz-the-decoder/pen/eKaLRd — заголовки прикрепленных карточек
- https://codepen.io/tutsplus/pen/abojPjP — тень заголовка цены при триггере
- https://codepen.io/kevinpowell/pen/KEjMEv — прикрепленные заголовки боковой панели разделов
Защелкнуто
С помощью запросов привязанного состояния мы можем снять часть ответственности с JavaScript и Snap Events и перенести обработку на CSS.
@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}
Небольшое напоминание: если вы пропустили раздел «Первый запрос состояния прокрутки» , контейнером для запроса привязки является элемент с scroll-snap-align
, а элемент, который может адаптироваться, должен быть дочерним элементом этого элемента. Это означает, что для настройки необходимы три элемента:
a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
⤷ a child of the snap target that can query the container for snap state
Визуально увеличить привязанный элемент
С помощью скроллера с центральной привязкой очень часто можно выделить или выделить элемент, привязанный к центру. В этом примере отзывов используется ключевое слово not
, поэтому все несвязанные отзывы имеют низкую непрозрачность, в то время как закрепленные отзывы остаются в своем естественном состоянии представления.
.demo {
overflow: auto hidden;
scroll-snap-type: x mandatory;
> article {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
> * {
transition: opacity .5s ease;
@container not scroll-state(snapped: x) {
opacity: .25;
}
}
}
}
}
Показать заголовок прикрепленного элемента
Это хороший пример того, как запросы состояния прокрутки включают анимацию, запускаемую прокруткой. Это также хороший пример того, как в CSS важно соблюдать ограничение движения.
.demo {
overflow-x: auto;
scroll-behavior-x: contain;
scroll-snap-type: x mandatory;
> .card {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
figcaption {
transform: translateY(100%);
@container scroll-state(snapped: x) {
transform: translateY(0);
}
}
}
}
}
}
Анимация в элементах слайда
Во время выступления очень часто анимируют элементы слайд-шоу или презентации. Раньше было довольно неприятно писать для этого обозреватель пересечений, который всего лишь устанавливал класс на слайде. Теперь нам не нужен никакой JavaScript.
html {
scroll-snap-type: y mandatory;
}
section {
container-type: scroll-state;
scroll-snap-align: start;
scroll-snap-stop: always;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
> h1 {
transition: opacity .5s ease, transform .5s var(--ease-spring-3);
transition-delay: .5s;
opacity: 0;
transform: scale(1.25);
@container scroll-state(snapped: block) {
opacity: 1;
transform: scale(1);
}
}
}
}
}
Вы могли заметить, что все привязанные запросы состояния CSS ведут себя как scrollsnapchanging
, а не как scrollsnapchange
. Это дает вам самый ранний крючок для обеспечения визуальной обратной связи привязываемого элемента. Если он слишком нетерпелив, рассмотрите событие JavaScript.
Прокручиваемый
Запрос состояния прокрутки будет очень полезен для демонстрации визуальных возможностей того, когда область прокрутки действительно можно прокручивать. До получения запросов о состоянии прокрутки эту информацию было сложно узнать .
@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}
Обозначить прокрутку тенями
Леа Веру использует знаменитый CSS-трюк , который использует background-attachment: local
для достижения эффекта, подобного этому, а также способ сделать это с помощью анимации, управляемой прокруткой . У каждого метода есть свои компромиссы, и нам предстоит выяснить, когда и где каждый из этих методов подходит лучше всего.
В следующем примере используется один липкий элемент, охватывающий область прокрутки. Непрозрачность градиента вверху и градиента внизу анимируется с помощью @property
когда применяется контекстный запрос состояния прокрутки: @container scroll-state(scrollable: top)
.
Также обратите внимание, что это первый контейнер, который одновременно является контейнером size
и scroll-state
.
.scroll-container {
container-type: scroll-state size;
overflow: auto;
&::after {
content: " ";
background: var(--_shadow-top), var(--_shadow-bottom);
transition:
--_scroll-shadow-color-1-opacity .5s ease,
--_scroll-shadow-color-2-opacity .5s ease;
@container scroll-state(scrollable: top) {
--_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
}
@container scroll-state(scrollable: bottom) {
--_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
}
}
}
Подсказка со стрелкой
Иногда отображение стрелки может помочь пользователям обнаружить, что область можно прокручивать. Они, как правило, указывают направление, в котором может происходить прокрутка, и исчезают, когда они больше не нужны. Вы можете сделать это с помощью следующего кода.
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
}
@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
rotate: .5turn;
}
Вернуться наверх
Еще одно популярное взаимодействие с состоянием прокрутки — это удобная кнопка «прокрутить вверх». Следующий код приводит к исчезновению кнопки прокрутки вверх, когда прокручивать вверх некуда.
Это решение немного перевернуто, но позволяет уменьшить количество CSS. Естественное место расположения кнопки видно, поэтому вам нужно указать ей, чтобы она скрывалась, когда больше некуда прокручивать вверх.
@container not scroll-state(scrollable: top) {
translate: 0 calc(100% + 10px);
}
Продолжение исследования
Если вы ищете больше, вот несколько ресурсов, которые варьируются от подробностей спецификаций до других замечательных статей по этой теме:
- Что еще мы должны иметь возможность выполнять запросы к контейнеру? https://github.com/w3c/csswg-drafts/issues/5989
- Объяснитель Scroll-state() - https://drafts.csswg.org/css-conditional-5/scroll_state_explainer.md
- Спецификация CSS Scroll-state() — https://www.w3.org/TR/css-conditional-5/#scroll-state-container
- Снимок макета в цикле событий HTML
- Эпизод подкаста о запросах штата — https://nerdy.dev/the-css-podcast-on-state-queries
- Еще статьи
- https://utilitybend.com/blog/is-the-sticky-thing-stuck-is-the-snappy-item-snapped-a-look-at-state-queries-in-css/
- https://ishadeed.com/article/css-state-queries/
- https://csscade.com/can-you-detect-overflow-with-css/
- https://css-tip.com/overflow-detection/ — обнаружение с помощью анимации, управляемой прокруткой, таким образом, что это могут знать не только дети (с компромиссом в отношении обмана)
Как контейнерные запросы; но для застрявших, зависших и переполненных запросов.
Опубликовано: 15 января 2025 г.
Chrome 133 основывается на запросах контейнеров, вводя запросы контейнеров с состоянием прокрутки. Управляемое браузером состояние для закрепленного позиционирования, точек привязки прокрутки и прокручиваемых элементов теперь можно запрашивать и адаптировать из CSS.
Обзор
Перед запросами состояния прокрутки вам нужно будет использовать JavaScript, чтобы понять, застрял ли элемент, защелкнулся или прокручивается. Теперь на пути стандартов появился более эффективный метод получения этой информации и соответствующей адаптации. Также появился новый способ запуска анимации, разблокирующий анимацию, запускаемую прокруткой, из CSS.
Вот обзор запросов состояния, доступных в Chrome 133:
- Состояние зависания :
- Стиль триггера меняется, когда элемент прилипает к краю.
- Зафиксированное состояние :
- Стиль триггера меняется, когда элемент привязывается к оси.
- Прокручиваемое состояние :
- Стиль триггера меняется, когда элемент переполнен.
Хорошая новость заключается в том, что все, что вы узнали из запросов к контейнерам, поможет вам работать с запросами состояния прокрутки.
Существует также неизведанная территория между анимацией, управляемой прокруткой , и запросами контейнера состояния прокрутки; нам нужно поэкспериментировать со временем и контекстом, чтобы определить, какая анимация, управляемая прокруткой, или анимация состояния прокрутки, запускаемая прокруткой, будет лучше. Следующее видео и демонстрация иллюстрируют затруднительное положение; липкая триггерная анимация по сравнению с анимацией, управляемой прокруткой.
Первый запрос состояния прокрутки
Первым шагом является определение контейнера, используя новое значение свойства container-type
. Как и в случае с запросом контейнера, элемент, который вы хотите запросить, — это тот элемент, которому вы указываете container-type
и, при необходимости, container-name
. С помощью запросов состояния прокрутки вы указываете элемент, который привязывается, застревает или имеет container-type: scroll-state
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
}
Второй шаг — выбрать дочерний элемент этого контейнера, который будет реагировать на состояние, поскольку в запросах контейнера это не может быть тот же элемент, который имеет container-type
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
Третий шаг — попробовать. В следующем примере CSS фон будет оформлен в красный цвет, когда элемент .stuck-top
прикрепится к верхнему значению 0
. Благодаря нескольким дополнительным строкам в CSS, которые мы уже написали, и дополнительному содержащему элементу, который передает состояние браузера, наши компоненты гораздо умнее относятся к своему окружению.
Прогрессивное улучшение
Правило @supports
и вложенность позволяют добавлять прогрессивное улучшение или условное использование функций всего за пару дополнительных строк кода:
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
@supports (container-type: scroll-state) {
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
}
Кроме того, не забудьте использовать @media (prefers-reduced-motion: no-preference) {}
для вашего движения, если в конечном итоге вам придется анимировать элементы на странице с помощью запросов состояния прокрутки.
Варианты использования
Застрявший
Возможно, этот раздел следует назвать «Неприятные ситуации»? Это небольшая коллекция сценариев использования закрепленных состояний, а также бонусный раздел идей, которые необходимо реализовать.
@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}
Добавить тень при застревании
Один из наиболее распространенных случаев использования зависшего запроса — это панели навигации, которые хотят добавить box-shadow
при зависании, чтобы они могли казаться плавающими над содержимым, которое они накладывают.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
transition: box-shadow .3s ease;
@container scroll-state(stuck: top) {
box-shadow: var(--shadow-5);
}
}
}
Активировать текущий застрявший заголовок
Другой распространенный сценарий закрепления обратной связи пользовательского интерфейса — выделение застрявшего в данный момент элемента. В списке групп, расположенных в алфавитном порядке, это может быть очень полезно и полезно для опыта.
.sticky-slide {
dt {
container-type: scroll-state;
position: sticky;
inset-block-start: 0;
inset-inline: 0;
> header {
transition:
background .3s ease,
box-shadow .5s ease;
@container scroll-state(stuck: top) {
background: hsl(265 100% 27%);
box-shadow: 0 5px 5px #0003;
}
}
}
}
Вот еще один вариант, в котором заголовки находятся сбоку от элементов списка. Множество возможностей!
Переполнение идей
Вот список запоминающихся демонстраций, которые могут вдохновить вас добавить в демо немного остроты или удалить JavaScript с помощью запросов состояния прокрутки. Я предлагаю попробовать создать тот, который вам понравится, это поможет сохранить синтаксис и идеи 😏.
- https://codepen.io/BlogFire/pen/PoGMjaX - вариант липких заметок
- https://codepen.io/mikegolus/pen/jOZzRzw — добавлять тени к таблице, когда они прилипают
- https://codepen.io/MarcRay/pen/PomBeP - панель навигации под заголовком появляется при триггере
- https://codepen.io/kevinpowell/pen/OqKJjK – отображение нижней панели навигации
- https://codepen.io/abhisekz-the-decoder/pen/eKaLRd — заголовки прикрепленных карточек
- https://codepen.io/tutsplus/pen/abojPjP — тень заголовка цены при триггере
- https://codepen.io/kevinpowell/pen/KEjMEv — прикрепленные заголовки боковой панели разделов
Защелкнуто
С помощью запросов привязанного состояния мы можем снять часть ответственности с JavaScript и Snap Events и перенести обработку на CSS.
@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}
Небольшое напоминание: если вы пропустили раздел «Первый запрос состояния прокрутки» , контейнером для запроса привязки является элемент с scroll-snap-align
, а элемент, который может адаптироваться, должен быть дочерним элементом этого элемента. Это означает, что для настройки необходимы три элемента:
a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
⤷ a child of the snap target that can query the container for snap state
Визуально увеличить привязанный элемент
С помощью скроллера с центральной привязкой очень часто можно выделить или выделить элемент, привязанный к центру. В этом примере отзывов используется ключевое слово not
, поэтому все несвязанные отзывы имеют низкую непрозрачность, в то время как закрепленные отзывы остаются в своем естественном состоянии представления.
.demo {
overflow: auto hidden;
scroll-snap-type: x mandatory;
> article {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
> * {
transition: opacity .5s ease;
@container not scroll-state(snapped: x) {
opacity: .25;
}
}
}
}
}
Показать заголовок прикрепленного элемента
Это хороший пример того, как запросы состояния прокрутки включают анимацию, запускаемую прокруткой. Это также хороший пример того, как в CSS важно соблюдать ограничение движения.
.demo {
overflow-x: auto;
scroll-behavior-x: contain;
scroll-snap-type: x mandatory;
> .card {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
figcaption {
transform: translateY(100%);
@container scroll-state(snapped: x) {
transform: translateY(0);
}
}
}
}
}
}
Анимация в элементах слайда
Во время выступления очень часто анимируют элементы слайд-шоу или презентации. Раньше было довольно неприятно писать для этого обозреватель пересечений, который всего лишь устанавливал класс на слайде. Теперь нам не нужен никакой JavaScript.
html {
scroll-snap-type: y mandatory;
}
section {
container-type: scroll-state;
scroll-snap-align: start;
scroll-snap-stop: always;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
> h1 {
transition: opacity .5s ease, transform .5s var(--ease-spring-3);
transition-delay: .5s;
opacity: 0;
transform: scale(1.25);
@container scroll-state(snapped: block) {
opacity: 1;
transform: scale(1);
}
}
}
}
}
Вы могли заметить, что все привязанные запросы состояния CSS ведут себя как scrollsnapchanging
, а не как scrollsnapchange
. Это дает вам самый ранний крючок для обеспечения визуальной обратной связи привязываемого элемента. Если он слишком нетерпелив, рассмотрите событие JavaScript.
Прокручиваемый
Запрос состояния прокрутки будет очень полезен для демонстрации визуальных возможностей того, когда область прокрутки действительно можно прокручивать. До получения запросов о состоянии прокрутки эту информацию было сложно узнать .
@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}
Обозначить прокрутку тенями
Леа Веру использует знаменитый CSS-трюк , который использует background-attachment: local
для достижения эффекта, подобного этому, а также способ сделать это с помощью анимации, управляемой прокруткой . У каждого метода есть свои компромиссы, и нам предстоит выяснить, когда и где каждый из этих методов подходит лучше всего.
В следующем примере используется один липкий элемент, охватывающий область прокрутки. Непрозрачность градиента вверху и градиента внизу анимируется с помощью @property
когда применяется контекстный запрос состояния прокрутки: @container scroll-state(scrollable: top)
.
Также обратите внимание, что это первый контейнер, который одновременно является контейнером size
и scroll-state
.
.scroll-container {
container-type: scroll-state size;
overflow: auto;
&::after {
content: " ";
background: var(--_shadow-top), var(--_shadow-bottom);
transition:
--_scroll-shadow-color-1-opacity .5s ease,
--_scroll-shadow-color-2-opacity .5s ease;
@container scroll-state(scrollable: top) {
--_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
}
@container scroll-state(scrollable: bottom) {
--_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
}
}
}
Подсказка со стрелкой
Иногда отображение стрелки может помочь пользователям обнаружить, что область можно прокручивать. Они, как правило, указывают направление, в котором может происходить прокрутка, и исчезают, когда они больше не нужны. Вы можете сделать это с помощью следующего кода.
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
}
@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
rotate: .5turn;
}
Вернуться наверх
Еще одно популярное взаимодействие с состоянием прокрутки — это удобная кнопка «прокрутить вверх». Следующий код приводит к исчезновению кнопки прокрутки вверх, когда прокручивать вверх некуда.
Это решение немного перевернуто, но позволяет уменьшить количество CSS. Естественное место расположения кнопки видно, поэтому вам нужно указать ей, чтобы она скрывалась, когда больше некуда прокручивать вверх.
@container not scroll-state(scrollable: top) {
translate: 0 calc(100% + 10px);
}
Продолжение исследования
Если вы ищете больше, вот несколько ресурсов, которые варьируются от подробностей спецификаций до других замечательных статей по этой теме:
- Что еще мы должны иметь возможность выполнять запросы к контейнеру? https://github.com/w3c/csswg-drafts/issues/5989
- Объяснитель Scroll-state() - https://drafts.csswg.org/css-conditional-5/scroll_state_explainer.md
- Спецификация CSS Scroll-state() — https://www.w3.org/TR/css-conditional-5/#scroll-state-container
- Снимок макета в цикле событий HTML
- Эпизод подкаста о запросах штата – https://nerdy.dev/the-css-podcast-on-state-queries
- Еще статьи
- https://utilitybend.com/blog/is-the-sticky-thing-stuck-is-the-snappy-item-snapped-a-look-at-state-queries-in-css/
- https://ishadeed.com/article/css-state-queries/
- https://csscade.com/can-you-detect-overflow-with-css/
- https://css-tip.com/overflow-detection/ — обнаружение с помощью анимации, управляемой прокруткой, таким образом, что это могут знать не только дети (с компромиссом в отношении обмана)