This media is not supported in your browser
VIEW IN TELEGRAM
#codepen дня
Кому в детстве нравилось крутить в руках всякие цепочки и кисточки для велосипедов?
Сегодня ваш шанс вспомнить то самое чувство!
Очередной прекрасный пример анимации по скроллу от Stijn Van Minnebruggen (я хз как произнести, это что-то из Евротура)
Тут: https://codepen.io/donotfold/pen/ZYYYJRV
Работает в Chrome и Safari TP.
Кто переведёт на GSAP? Он, кстати, недавно официально бесплатным стал, даже для коммерческого использования.
#css #scroll #animation #бородач
Кому в детстве нравилось крутить в руках всякие цепочки и кисточки для велосипедов?
Сегодня ваш шанс вспомнить то самое чувство!
Очередной прекрасный пример анимации по скроллу от Stijn Van Minnebruggen (я хз как произнести, это что-то из Евротура)
Тут: https://codepen.io/donotfold/pen/ZYYYJRV
Работает в Chrome и Safari TP.
Кто переведёт на GSAP? Он, кстати, недавно официально бесплатным стал, даже для коммерческого использования.
#css #scroll #animation #бородач
❤5🤩2
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня
Сделали вы такие флекс-контейнер, потомки в колонку, по центру, красота.
Но тут что-то пошло не так и контейнер стал слишком узким. Появился скролл. Казалось бы, невелика потеря: пользователь поскроллит.
А вот фиг!
Контейнер просто обрежет самого широкого потомка и не даст посмотреть его содержимого.
Что же делать?
Очень просто, Стефан Юдис напоминает нам о существовании ключевого слова safe, которое можно передать аргументом в align-правило:
Смотрим видео. Теперь можно будет спокойно доскроллить до края самого широкого элемента.
Подробнее: https://www.stefanjudis.com/today-i-learned/safe-unsafe-alignment-in-css-flexbox/
По поводу поддержки браузерами: Chrome со 115 и Firefox с 63. И — ура — Safari с 17.6. В прошлый раз когда я эту статью упоминал — поддержка в Safari была только в TP.
А еще там Safari 26 вышла с поддержкой анимаций по скроллу, будем скоро вспоминать. Слава богу, macOS 26 для этого ставить не нужно.
#flex #css #scroll #бородач
Сделали вы такие флекс-контейнер, потомки в колонку, по центру, красота.
Но тут что-то пошло не так и контейнер стал слишком узким. Появился скролл. Казалось бы, невелика потеря: пользователь поскроллит.
А вот фиг!
Контейнер просто обрежет самого широкого потомка и не даст посмотреть его содержимого.
Что же делать?
Очень просто, Стефан Юдис напоминает нам о существовании ключевого слова safe, которое можно передать аргументом в align-правило:
.container {
display: flex;
flex-direction: column;
align-items: safe center;
width: 50%;
}Смотрим видео. Теперь можно будет спокойно доскроллить до края самого широкого элемента.
Подробнее: https://www.stefanjudis.com/today-i-learned/safe-unsafe-alignment-in-css-flexbox/
По поводу поддержки браузерами: Chrome со 115 и Firefox с 63. И — ура — Safari с 17.6. В прошлый раз когда я эту статью упоминал — поддержка в Safari была только в TP.
А еще там Safari 26 вышла с поддержкой анимаций по скроллу, будем скоро вспоминать. Слава богу, macOS 26 для этого ставить не нужно.
#flex #css #scroll #бородач
👍12❤4
#фишка дня
Пишешь чат или выводишь данные лога в консоль и хочешь чтобы каждое новое сообщение снизу было видимым?
Ни слова больше! Спека has us covered: https://drafts.csswg.org/css-scroll-snap/#example-d0a2d86f
Удивительное дело, конечно, видеть примеры прямо в черновике спецификации :)
Вот, кстати, пример от Брамуса Ван Дамма: https://codepen.io/bramus/pen/PorRORd
Обратите внимание, за нас подумали, что пользователь может поскроллить наверх.
На старых версиях Chrome иногда проявляется баг с пружинящим скроллом — Chrome теряет событие и «снапит» нас назад, но недавно и это пофиксили.
Ну если вы за старое доброе решение на JavaScript, вот, держите хук от Vercel.
#scroll #snap #css #бородач
Пишешь чат или выводишь данные лога в консоль и хочешь чтобы каждое новое сообщение снизу было видимым?
Ни слова больше! Спека has us covered: https://drafts.csswg.org/css-scroll-snap/#example-d0a2d86f
Удивительное дело, конечно, видеть примеры прямо в черновике спецификации :)
Вот, кстати, пример от Брамуса Ван Дамма: https://codepen.io/bramus/pen/PorRORd
Обратите внимание, за нас подумали, что пользователь может поскроллить наверх.
На старых версиях Chrome иногда проявляется баг с пружинящим скроллом — Chrome теряет событие и «снапит» нас назад, но недавно и это пофиксили.
Ну если вы за старое доброе решение на JavaScript, вот, держите хук от Vercel.
#scroll #snap #css #бородач
👍17❤2
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня
Кому адекватной современной виртуализации списков?
Как-то так повелось, что задача отрисовки десятков, и даже сотен тысяч строк или ячеек на экране решается... волнами. Появляется решение, принимается всеми, а потом — буквально забрасывается. И вот мы годами ждём обновления того же react-window просто чтобы получить возможность рендерить строки разной высоты из коробки. А react-window сам по себе был и является рекомендованной заменой react-virtualized.
В других фреймворках и ванильных средах ситуация ещё веселее.
При этом разработчики, например, мобильных приложений на тех же Flutter и SwiftUI в принципе лишены этой проблемы, просто потому что им надо заботиться о рендере элементов самостоятельно, заранее объявляя, что тут должен быть скролл. Насильная виртуализация, так сказать.
Если вы были застигнуты врасплох моими утверждениями и не понимаете вообще, о чём я, то вкратце поясню: чтобы дать возможность человеку поскроллить тысячи и сотни тысяч объектов на экране, совсем не обязательно отрисовывать их все разом. Можно отрисовать штук 10-20 строк, заполнив экран, и просто переиспользовать эти элементы раз за разом. Виртуальные списки, буквально.
Итак, для чего я всё это пишу? А вот: вашему вниманию предъявляется универсальная библиотека виртуализации списков virtua.
GitHub: https://github.com/inokawa/virtua
Умеет в динамические высоты строк из коробки! Умеет в бесконечный скролл. Умеет занимать всю высоту окна. Умеет в RSC.
Ну и не ограничивается одним только React: Vue, Solid и Svelte тоже поддерживаются.
Отличное современное решение.
#scroll #virtual #бородач
Кому адекватной современной виртуализации списков?
Как-то так повелось, что задача отрисовки десятков, и даже сотен тысяч строк или ячеек на экране решается... волнами. Появляется решение, принимается всеми, а потом — буквально забрасывается. И вот мы годами ждём обновления того же react-window просто чтобы получить возможность рендерить строки разной высоты из коробки. А react-window сам по себе был и является рекомендованной заменой react-virtualized.
В других фреймворках и ванильных средах ситуация ещё веселее.
При этом разработчики, например, мобильных приложений на тех же Flutter и SwiftUI в принципе лишены этой проблемы, просто потому что им надо заботиться о рендере элементов самостоятельно, заранее объявляя, что тут должен быть скролл. Насильная виртуализация, так сказать.
Если вы были застигнуты врасплох моими утверждениями и не понимаете вообще, о чём я, то вкратце поясню: чтобы дать возможность человеку поскроллить тысячи и сотни тысяч объектов на экране, совсем не обязательно отрисовывать их все разом. Можно отрисовать штук 10-20 строк, заполнив экран, и просто переиспользовать эти элементы раз за разом. Виртуальные списки, буквально.
Итак, для чего я всё это пишу? А вот: вашему вниманию предъявляется универсальная библиотека виртуализации списков virtua.
GitHub: https://github.com/inokawa/virtua
Умеет в динамические высоты строк из коробки! Умеет в бесконечный скролл. Умеет занимать всю высоту окна. Умеет в RSC.
Ну и не ограничивается одним только React: Vue, Solid и Svelte тоже поддерживаются.
Отличное современное решение.
#scroll #virtual #бородач
❤13
#заметка дня
Вот то самое откровение, которое я обещал в новости о jQuery 4.0.
В Chrome 145 будет изменено поведение 100vw. Браузер будет учитывать ширину скроллбара, исключая горизонтальную прокрутку.
Ссылка: https://www.bram.us/2026/01/15/100vw-horizontal-overflow-no-more/
И да, это будет ломающее изменение.
Хотя, если честно, я не очень понимаю людей, которым вообще нужно было значение 100vw, это же дефолт блочных структур.
Старое поведение по факту годами создавало баг, с которым разработчики либо мирились, либо прятали его костылями — через
Самый показательный момент — реальные цифры.
Через HTTP Archive было проанализировано 12 089 606 корневых страниц. Из них 324 866 сайтов, то есть примерно 2.7%, в принципе использовали
Вот комментарий в PR спеки: https://github.com/w3c/csswg-drafts/issues/6026#issuecomment-1919428550
Это хорошо показывает реальную картину: подавляющее большинство разработчиков никогда не «считали скроллбар». Они либо избегали 100vw, либо жили с лишним горизонтальным скроллом, либо просто добавляли overflow-x: hidden. То есть проблема была массовой, а осознанно решали её — доли процента.
Именно поэтому браузеры и пошли на ломающее изменение. Старое поведение не было полезной фичей, это была историческая особенность, которая порождала баги чаще, чем решала реальные задачи. В итоге решили сломать редкие кейсы ради того, чтобы 100vw наконец означал то, что от него ожидают почти все.
Хороший пример того, сколько инженерной работы уходит на полировку вещей, которые пользователи, возможно, и не заметят напрямую, но которые годами раздражали фронтендеров.
И хороший вопрос, какой процент разработчиков морочится с чем-то менее видным, если даже на возможные скроллбары всем пофигу...
#css #scroll
Вот то самое откровение, которое я обещал в новости о jQuery 4.0.
В Chrome 145 будет изменено поведение 100vw. Браузер будет учитывать ширину скроллбара, исключая горизонтальную прокрутку.
Ссылка: https://www.bram.us/2026/01/15/100vw-horizontal-overflow-no-more/
И да, это будет ломающее изменение.
Хотя, если честно, я не очень понимаю людей, которым вообще нужно было значение 100vw, это же дефолт блочных структур.
Старое поведение по факту годами создавало баг, с которым разработчики либо мирились, либо прятали его костылями — через
calc. Самый показательный момент — реальные цифры.
Через HTTP Archive было проанализировано 12 089 606 корневых страниц. Из них 324 866 сайтов, то есть примерно 2.7%, в принципе использовали
calc() рядом с 100vw. При этом явные попытки компенсировать ширину скроллбара встречаются крайне редко: порядка 4 000 сайтов принудительно задают overflow: scroll на <html>, и всего несколько десятков страниц используют calc(100vw - …) именно для учёта скроллбара.Вот комментарий в PR спеки: https://github.com/w3c/csswg-drafts/issues/6026#issuecomment-1919428550
Это хорошо показывает реальную картину: подавляющее большинство разработчиков никогда не «считали скроллбар». Они либо избегали 100vw, либо жили с лишним горизонтальным скроллом, либо просто добавляли overflow-x: hidden. То есть проблема была массовой, а осознанно решали её — доли процента.
Именно поэтому браузеры и пошли на ломающее изменение. Старое поведение не было полезной фичей, это была историческая особенность, которая порождала баги чаще, чем решала реальные задачи. В итоге решили сломать редкие кейсы ради того, чтобы 100vw наконец означал то, что от него ожидают почти все.
Хороший пример того, сколько инженерной работы уходит на полировку вещей, которые пользователи, возможно, и не заметят напрямую, но которые годами раздражали фронтендеров.
И хороший вопрос, какой процент разработчиков морочится с чем-то менее видным, если даже на возможные скроллбары всем пофигу...
#css #scroll
👍18❤6
Media is too big
VIEW IN TELEGRAM
#фишка дня
Использование
А что если можно было бы обращаться к элементам прилипшего родителя и что-то странное с ними вытворять?
Так можно! Для этого у нас буквально не так давно появились скролл-запросы, как часть контейнерных запросов. Так и называются: Container scroll-state queries.
Например, хотите сделать картинку в картинке? Ну, чтобы, например, не блокировать чтение статьи?
Или, наоборот, не прерывать просмотр рекламы? :)
Запросто: https://codepen.io/alinaki/pen/WbvMOPB
Обратите внимание,
А для браузеров, которые в скролл-запросы пока не умеют, всегда можно написать короткий IntersectionObserver (он, кстати, есть в примере).
#css #scroll #state #бородач
Использование
position: sticky уже так-то стало обыденностью.А что если можно было бы обращаться к элементам прилипшего родителя и что-то странное с ними вытворять?
Так можно! Для этого у нас буквально не так давно появились скролл-запросы, как часть контейнерных запросов. Так и называются: Container scroll-state queries.
Например, хотите сделать картинку в картинке? Ну, чтобы, например, не блокировать чтение статьи?
Или, наоборот, не прерывать просмотр рекламы? :)
Запросто: https://codepen.io/alinaki/pen/WbvMOPB
@container scroll-state(stuck: top) {
.pip {
width: 200px;
transform: translate(-50%, 0%)
translate(calc(50vw - (50% + 1rem)), calc(100vh - (100% + 1rem)));
}
}
Обратите внимание,
translate можно складывать, получая интересную математику в итоге :)А для браузеров, которые в скролл-запросы пока не умеют, всегда можно написать короткий IntersectionObserver (он, кстати, есть в примере).
#css #scroll #state #бородач
❤16👍7🤩5
#cтатья дня
Почти три года назад у меня неплохо так бомбануло на тему недоделанности фишек в современном вебе.
Да, мне не очень нравятся статьи и посты на тему того, как скоро всем будет хорошо, надо лишь немножечко подождать. В итоге, нет, не немножечко. Ну, может, на срезе 20 лет... (спойлер: тоже не факт).
Ладно, сегодня я конкретно хочу поговорить о состоянии
Я тут немного пропустил, но в Chrome 133 состояние
Да, понятие контейнер было мной упомянуто не просто так — эта красота теперь часть контейнерных запросов. И с этим меня познакомила прекрасная статья от Брехта де Рёйте: https://utilitybend.com/blog/is-it-scrolled-is-it-not-lets-find-out-with-css-container-scroll-state-queries/
Так вот, суть-то в том, что в свежем Chrome 144 появилась и поддержка состояния
Ну это ли не чудо? А если указать
Кстати, есть и статья на MDN.
Да, очень грустно, что Safari и Firefox пока не шевелятся, но это в принципе можно решить полифиллами. Главное, что направление задано.
Но бомбить от недоделанности новых фишек пока не перестало.
#css #scroll #state
Почти три года назад у меня неплохо так бомбануло на тему недоделанности фишек в современном вебе.
Да, мне не очень нравятся статьи и посты на тему того, как скоро всем будет хорошо, надо лишь немножечко подождать. В итоге, нет, не немножечко. Ну, может, на срезе 20 лет... (спойлер: тоже не факт).
Ладно, сегодня я конкретно хочу поговорить о состоянии
scrolled и stuck для контейнеров. Очевидно, scrolled — это когда мы прокрутили в какую-то сторону, а stuck — это когда при использовании position: sticky мы можем определить, закрепился элемент, или нет.Я тут немного пропустил, но в Chrome 133 состояние
stuck таки появилось:
.scroll-ancestor {
container-type: scroll-state;
}
@container scroll-state(stuck: top) {
.child-of-scroll-parent {
/* Magic happens here! */
}
}
Да, понятие контейнер было мной упомянуто не просто так — эта красота теперь часть контейнерных запросов. И с этим меня познакомила прекрасная статья от Брехта де Рёйте: https://utilitybend.com/blog/is-it-scrolled-is-it-not-lets-find-out-with-css-container-scroll-state-queries/
Так вот, суть-то в том, что в свежем Chrome 144 появилась и поддержка состояния
scrolled, да-да, с указанием направления!
/* If the last scroll was UP, show the header */
@container scroll-state(scrolled: top) {
.main-header {
transform: translateY(0);
}
}
Ну это ли не чудо? А если указать
inline или block, можно скрыть/показать индикаторы возможности скролла вообще. То же касается и индивидуальных направлений.Кстати, есть и статья на MDN.
Да, очень грустно, что Safari и Firefox пока не шевелятся, но это в принципе можно решить полифиллами. Главное, что направление задано.
Но бомбить от недоделанности новых фишек пока не перестало.
#css #scroll #state
1❤10🤩2👍1
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня
У скроллящегося сайдбара можно сделать fade по краям так, чтобы пункты меню как будто уходили под градиент сверху и снизу. И сделать это красиво.
Сразу пример со всем кодом и описанием: https://codepen.io/editor/alinaki/pen/019d954a-79e7-7e49-8653-181b0b67ad61
Для этого используется mask-image, а управляет всем scroll timeline: скролл контейнера становится прогрессом CSS-анимации. Дальше анимация меняет стопы градиента в маске, поэтому в начале верхний fade выключен, после начала прокрутки появляется, а в конце исчезает нижний.
Важный момент в том, что здесь не двигается сам градиент и не меняется opacity списка. Меняются именно стопы градиента, и из-за этого fade ведёт себя как часть скролла, а не как отдельный декоративный слой.
Если хочется понять глубже, смотреть стоит в сторону animation-timeline, scroll-timeline и обзора scroll-driven animations.
Upd. добавил светлую тему, чтобы разница была виднее.
#css #scroll
У скроллящегося сайдбара можно сделать fade по краям так, чтобы пункты меню как будто уходили под градиент сверху и снизу. И сделать это красиво.
Сразу пример со всем кодом и описанием: https://codepen.io/editor/alinaki/pen/019d954a-79e7-7e49-8653-181b0b67ad61
Для этого используется mask-image, а управляет всем scroll timeline: скролл контейнера становится прогрессом CSS-анимации. Дальше анимация меняет стопы градиента в маске, поэтому в начале верхний fade выключен, после начала прокрутки появляется, а в конце исчезает нижний.
@keyframes sidebar-fade-mask {
0% { --fade-top-end: 0%; --fade-bottom-start: 94%; --fade-bottom-end: 99%; }
8%, 92% { --fade-top-end: 6%; --fade-bottom-start: 94%; --fade-bottom-end: 99%; }
100% { --fade-top-end: 6%; --fade-bottom-start: 100%; --fade-bottom-end: 100%; }
}
.menu-scroll {
animation: sidebar-fade-mask auto linear both;
animation-timeline: scroll(self block);
mask-image: linear-gradient(
to bottom,
transparent 0%,
#000 var(--fade-top-end),
#000 var(--fade-bottom-start),
transparent var(--fade-bottom-end)
);
}
Важный момент в том, что здесь не двигается сам градиент и не меняется opacity списка. Меняются именно стопы градиента, и из-за этого fade ведёт себя как часть скролла, а не как отдельный декоративный слой.
Если хочется понять глубже, смотреть стоит в сторону animation-timeline, scroll-timeline и обзора scroll-driven animations.
Upd. добавил светлую тему, чтобы разница была виднее.
#css #scroll
👍20❤3🤩2
This media is not supported in your browser
VIEW IN TELEGRAM
#статья дня
Scroll-driven animations уже давно есть в Chrome, и за последний год вокруг них накопилось много примеров — у того же Bramus Van Damme были подробные демки с
Как всегда, это интерактивная документация по
Посмею себе напомнить ключевую идею процесса: прогресс анимации берётся не из времени (`animation-duration`), а из положения элемента относительно viewport или scroll-контейнера. В статье это сразу показывается на примере с progress bar, где значение анимации напрямую связано со скроллом страницы.
Дальше он последовательно вводит
Отдельно разбирается
Есть демонстрации с несколькими timeline’ами и синхронизацией анимаций, где один scroll-прогресс управляет сразу несколькими свойствами.
Практически в каждом блоке есть интерактив: можно скроллить вложенные контейнеры и сразу видеть, как меняется поведение.
Документация: https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timeline
Примеры от Google: https://developer.chrome.com/docs/css-ui/scroll-driven-animations/
Из нюансов — Safari всё ещё отстаёт: часть API отсутствует или работает неполно, так что без фоллбеков пока не обойтись.
#css #scroll
Scroll-driven animations уже давно есть в Chrome, и за последний год вокруг них накопилось много примеров — у того же Bramus Van Damme были подробные демки с
view-timeline и разными вариантами ranges. Теперь появился ещё один большой разбор от самого Джоша Комо: https://www.joshwcomeau.com/animation/scroll-driven-animations/Как всегда, это интерактивная документация по
animation-timeline.Посмею себе напомнить ключевую идею процесса: прогресс анимации берётся не из времени (`animation-duration`), а из положения элемента относительно viewport или scroll-контейнера. В статье это сразу показывается на примере с progress bar, где значение анимации напрямую связано со скроллом страницы.
Дальше он последовательно вводит
scroll-timeline и view-timeline. Первый вариант привязывается к прокрутке контейнера, второй — к тому, как конкретный элемент входит и выходит из viewport. Есть наглядные демо, где один и тот же @keyframes ведёт себя по-разному в зависимости от выбранного таймлайна.Отдельно разбирается
animation-range. На интерактивных примерах видно, как entry, exit, cover, contain влияют на диапазон, в котором проигрывается анимация.Есть демонстрации с несколькими timeline’ами и синхронизацией анимаций, где один scroll-прогресс управляет сразу несколькими свойствами.
Практически в каждом блоке есть интерактив: можно скроллить вложенные контейнеры и сразу видеть, как меняется поведение.
Документация: https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timeline
Примеры от Google: https://developer.chrome.com/docs/css-ui/scroll-driven-animations/
Из нюансов — Safari всё ещё отстаёт: часть API отсутствует или работает неполно, так что без фоллбеков пока не обойтись.
#css #scroll
👍6