Как запускать CSS-анимацию при прокрутке страницы
В этом пошаговом руководстве будет рассмотрено создание CSS-анимации с нуля и её включение при скролле (прокрутке вверх-вниз) страницы, когда HTML-элемент находится в поле зрения — видимой части окна, с помощью Intersection Observer API.
Настройка CSS-анимации с помощью ключевых кадров
Начнем с создания CSS-анимации, которая определяется ключевыми кадрами @keyframes .
Анимацию можно назвать как угодно, пусть будет wipe-enter . Здесь HTML-элемент будет увеличиваться в ширину, а затем в высоту.
После того, как определены ключевые кадры, можно использовать анимацию для элемента, установив свойству animation-name название ключевых кадров: wipe-enter . Кроме этого необходимо установить animation-duration — продолжительность анимации и animation-iteration-count — счетчик итераций, указывающий, сколько раз анимация должна воспроизводиться, например — бесконечно.
CSS-класс .square пусть будет заключён в медиа-запрос prefers-reduce-motion: no-preference . Это обеспечит запуск анимации только в том случае, если пользователь не ограничил её и не включил параметр «уменьшить движение» в своей операционной системе.
В этом примере будет анимирован HTML-элемент квадратной формы:
Для CSS-анимации можно использовать сокращённое написание свойства animation , например:
Управление анимацией с помощью CSS-класса
Допустим, не нужно, чтобы анимация воспроизводилась сразу. Воспроизведением анимации можно управлять, добавляя HTML-элементу CSS-класс переключатель только анимации, который не используется для остальной стилизации элемента.
CSS-анимация будет воспроизводиться, когда HTML-элементу будет добавлен CSS-класс .square-animation :
В этом примере CSS-анимация воспроизводится не каждый раз при нажатии на кнопку, а только тогда, когда HTML-элементу будет добавлен CSS-класс .square-animation .
Несмотря на то, что анимация должна показывать появление элемента, элемент отображается и до добавления класса .square-animation . Это сделано для того, чтобы при первой загрузке элемент был виден пользователю, даже если JavaScript заблокирован или не работает.
Добавление CSS-класса, когда элемент появляется при скролле (прокрутке страницы вверх-вниз)
В примере выше была реализована CSS-анимация, которая запускается при добавлении HTML-элементу CSS-класса. Вместо перехвата события нажатия кнопки, для добавления и удаления CSS-класса можно использовать несколько вариантов обнаружения состояния, когда элемент при скролле появляется в видимой части окна.
Вот три способа определить, когда элемент находится в видимой области окна:
- Использовать Intersection Observer API
- Измерять смещение элемента при скролле страницы
- Использовать стороннюю JavaScript-библиотеку, которая реализует №1 или №2
Для базовой анимации с запуском при скролле, оптимально использование Intersection Observer API, потому что он требует меньше кода, удобнее и лучше с точки зрения производительности.
API-интерфейс Intersection Observer позволяет отслеживать момент пересечения одного элемента с другим, и сообщает, когда это происходит. Этот способ идеально подходит для запуска CSS-анимации при скролле страницы. Всё, что нужно знать — когда HTML-элемент пересекается с окном просмотра. Если он пересекается, значит — находится в видимой области окна и в этот момент надо запустить CSS-анимацию.
Intersection Observer API можно рассматривать, как обычный слушатель событий, но с некоторыми дополнительными опциями. Вместо того, чтобы прикреплять прослушивание событий к HTML-элементу, надо заставить наблюдателя отслеживать элемент и его положение на странице.
Начнём с создания наблюдателя и заставим его отслеживать HTML-элемент:
По умолчанию корневым элементом, который будет проверяться на пересечение, является окно браузера, поэтому наблюдателю нужно только сообщить об анимируемом HTML-элементе.
Когда функция обратного вызова (callback) запускается, она возвращает массив записей из целевых (target) элементов, которые были запрошены, а также некоторую дополнительную информацию о них. В функцию всегда будет возвращаться массив, даже если наблюдение ведётся только за одним элементом, как здесь.
В функции обратного вызова можно перебрать массив записей, чтобы указать, что с ними нужно сделать. Каждая запись имеет свойство isIntersecting , которое может быть true или false . Если оно возвращает true , это означает, что элемент находится в видимой области окна (viewport).
Собираем всё вместе. Обратите внимание, что entry — это объект, предоставленный наблюдателем, а entry.target — это фактический элемент, за которым который ведется наблюдение, поэтому именно ему нужно добавить CSS-класс для запуска анимации.
Теперь, когда HTML-элемент пересекает границы окна браузера, ему будет добавлен CSS-класс, который будет воспроизводить анимацию.
Если нужно, чтобы анимация запускалась каждый раз, когда HTML-элемент входит в видимую область окна, необходимо удалять CSS-класс запуска анимации, когда он находится за пределами видимой области окна.
Если элемент при анимации изменяет размер или положение, браузеру может быть сложно решить, находится ли элемент в данный момент в области просмотра или нет. Лучше всего поместить анимируемый элемент в контейнер, который не изменяет размер или положение и использовать его для наблюдения за скролллом.
Теперь надо наблюдать за HTML-элементом c CSS-классом square-wrapper а класс для анимации применять к элементу с классом square , как и прежде. Когда элемент-оболочка находится за пределами видимой области, нужно удалять CSS-класс у элемента .square , чтобы анимация перезапускалась каждый раз, когда элемент появляется в окне при скролле.
Чтобы элемент-оболочку было видно, для примера, ему добавлена пунктирная рамка. Попробуйте прокрутить вверх и вниз документ в окне ниже:
Теперь — порядок! Добавляя и удаляя CSS-класс каждый раз, когда при скролле страницы HTML-элемент входит в область просмотра, запускается CSS-анимация.
Запуск CSS-transition при скролле
Если для анимации используется только один шаг и не требуется применение @keyframes , например, достаточно изменения прозрачности HTML-элемента от 0 до 1, можно использовать CSS-transition вместо CSS-animation.
Метод по сути тот же. Вместо определения ключевых кадров ( @keyframes ) для CSS-класса анимации указаны свойства для transition .
Заставим HTML-элемент появляться, когда он перемещается в видимую область просмотра. Для этого в момент появления в окне при скролле ему надо добавить CSS-класс square-transition . Так пользователь, у которого заблокирован или не загружается JavaScript, должен всё-равно увидеть HTML-элемент в его окончательном состоянии.
Это особенно важно, поскольку анимация начинается с opacity: 0 . Если бы не было настройки CSS-класса square-transition и JavaScript не работал, пользователь вообще не увидел бы HTML-элемент! Но если эффект перехода заключается в том, чтобы что-то исчезло, наверное, это не понадобится делать.
При первом запуске JavaScript нужно удалить CSS-класс, чтобы затем, его можно было добавить обратно, когда действительно нужно запустить transition . Это должно быть сделано вне метода обработки наблюдения за скроллом, желательно в начале JavaScript. Вот полный код:
В этом примере CSS-transition запускается, когда элемент-оболочка при скролле появляется в окне. Если Javascript не запустился, элемент всё-равно будет виден.
Как видите, эту технику можно расширять разными способами, чтобы создать множество эффектов анимации.
Плавное появление блока CSS
Пример HTML структуры. Два блока: первый видимый, при наведении на который будем плавно показывать второй (скрытый) элемент.
Всплывающий блок может содержать абсолютно любой контент: текст, картинку, видео и т.п.
Плавность появления и исчезновения работает за счёт добавления transition к свойствам opaciy и visibility
До скрытого элемента мы добрались с помощью родственного селектора
(тильда). Также можно было обратиться при помощи соседнего селектора + или дочернего >
Пример с более сложной структурой
Допустим, у нас следующая структура
Тогда CSS будет следующий
Таким образом, используя различные селекторы мы можем обратиться к последующим элементам для дальнейшей работы с ними.
Надеюсь, вам понравилась данная информация. Если вам интересна тема web-разработки, то можете следить за выходом новых статей в Telegram.
Плавное появление блока css при загрузке страницы
Сразу приведу ссылку на отдельную страницу, где и продемонстрируем, что будем делать:
Основной каркас для плавно появляющегося блока, блоков
У нас будет три строки, которые будет поваляться разнонаправленно!
Блок h1 + class="begin" будут плавно появляться слtва.
Блок абзаца "<p>", будет плавно появляться справа.
У нас есть основной блок. Который с позиционирован абсолютно(position: absolute;), вы его положения видите после загрузки страницы.
Нас прежде всего интересует:
Механизм работы плавно появляющегося блока:
У нас есть два блока( "h1" и ".begin"), для них будут прописаны свойство появление слева.
И блок между ними, который будет поваляться слева это абзац "<p>".
Для блоков слева выставляем
Для блоков справа :
keyframes для левого блока:
keyframes для правого го блока:
Соберем весь CSS:
div.main .center h1 <
font-size: calc(16px + 1.2vw);
animation: showLeft 1s;
Про остальные стили не вижу никакого смысла писать.
Результат плавного появления блока на примере + скачать
Плавное появление блока.
Давайте сразу приведем пару ссылок, что будем делать и где скачать:
В данном случае картинка, как иллюстрация для заполнения внутренней площади блока. что-то же должно показываться. картинка в данном случае будет выступать заменителем блока!
В общем то, код довольно простой. Просто я тут перебирал старые страницы и смотрю, а вот такого варианта на данной странице нет — думаю не порядок, такой простой вариант медленного появления блока должен здесь быть :
Убираем все отступы наружные и внутренние :
Скроем колесо прокрутки, если она вдруг появится.
Позиционируем, растягиваем, заполняем.
Добавляем keyframes, от полной невидимости(opacity: 0;) до полной видимости(opacity: 1;)
Не забываем по блок, который будет у нас появляться
Собираем все вместе и получаем блок появляющийся постепенно:
Локальное плавное появление блока.
Если вам нужен простой код плавного появления блока, то следующий пункт про такой блок.