Фоновая волна на простом CSS
Рассмотрим в этой статье, как сделать фоновые волны на сайте, используя только возможности CSS3 и SVG файл. Т.е. без применения Javascript.
Содержание:
Переходы между страницами выглядят очень, очень круто. Более того, они начинают появляться повсюду. Уверены, что вы, как и мы, не раз встречали в сети такие переходы, от которых у вас возникает восхищение и желание немедленно использовать их на своем сайте или в проекте.
В то же время поначалу бывает непросто разобраться с переходами между страницами. Они могут быть простыми, конечно, но в большинстве случаев, помимо плавного перехода, используется несколько движущихся элементов.
Мы считаем, что лучший способ научиться чему-то новому — это посмотреть код, использовать его самому, а затем дорабатывать. Поэтому мы собрали семь рецептов переходов между представлениями. Мы рассмотрим базовую настройку, продемонстрируем рецепты и дадим вам возможность поэкспериментировать!
Вы вполне можете просто скопировать тот вариант, который вам больше всего нравится, но если вы хотите понять, что такое переходы между представлениями, то мы рекомендуем сначала ознакомиться с кратким введением, прежде чем переходить к рецептам.
Да, и прежде чем мы перейдем к делу, стоит отметить, что на момент написания этой статьи переходы между представлениями действительно являются базовыми и поддерживаются всеми основными браузерами. Но некоторые типы анимации могут поддерживаться или не поддерживаться в конкретном браузере, так что следите за этим и, как всегда, тестируйте.
Для каждого перехода между представлениями нам нужно будет предварительно выполнить небольшую настройку. Во-первых, нам нужно согласиться на их использование с помощью @view-transition* на обеих страницах — на той, на которой мы находимся, и на той, на которую мы переходим. Если вы используете шаблоны на своем сайте, то этот код можно разместить в шаблоне верхнего колонтитула, чтобы он применялся глобально.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: <transition-type>;
}
}
<transition-type> — это единственная часть, которую нельзя скопировать и вставить напрямую. Это заполнитель для дескриптора types. Здесь есть свои нюансы, но types — это, по сути, название анимации, которое мы присваиваем конкретному переходу. Таким образом, если мы работаем с несколькими переходами, мы можем явно указать, какие из них активны, чтобы они не конфликтовали друг с другом. Но чтобы узнать больше, прочтите статью по ссылке.
Обратите внимание, что @view-transition скрыто за медиазапросом prefers-reduced-motion: no-preference . Не всем нужно, чтобы на страницах что-то двигалось, и это можно настроить на уровне операционной системы, поэтому при необходимости мы будем учитывать это.
Наконец, применим анимацию следующим образом:
html:active-view-transition-type(<transition-type>)::view-transition-old(root) {
animation: a-cool-outgoing-animation 1.4s ease forwards;
}
html:active-view-transition-type(<transition-type>)::view-transition-new(root) {
animation: a-cool-incoming-animation 1.4s ease forwards;
}
...где псевдоэлемент :active-view-transtion-type() соответствует переходу type, который мы определяем в правиле @view-transition . Например, если мы вызываем анимацию с именем bounce, то по правилам мы используем его следующим образом:
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: <transition-type>;
}
}
...а также псевдоним вроде такого:
/* The "current" page */
html:active-view-transition-type(bounce)::view-transition-old(root) {
animation: bounce-in 1.4s ease forwards;
}
/* The page we're transitioning to */
html:active-view-transition-type(bounce)::view-transition-new(root) {
animation: bounce-in 1.4s ease forwards;
}
Что ж, этого контекста достаточно, чтобы приступить к рецептам. Опять же, не стесняйтесь использовать любой из них в своих экспериментах или проектах.
Это что-то вроде простого кроссфейда, но с размытием: содержимое старой страницы постепенно исчезает, а содержимое новой появляется.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: pixelate-dissolve;
}
}
html:active-view-transition-type(pixelate-dissolve)::view-transition-old(root) {
animation: pixelate-out 1.4s ease forwards;
}
html:active-view-transition-type(pixelate-dissolve)::view-transition-new(root) {
animation: pixelate-in 1.4s ease forwards;
}
@keyframes pixelate-out {
0% {
filter: blur(0px);
opacity: 1;
}
100% {
filter: blur(40px);
opacity: 0;
}
}
@keyframes pixelate-in {
0% {
filter: blur(40px);
opacity: 0;
}
100% {
filter: blur(0px);
opacity: 1;
}
}
Здесь мы используем свойство clip-path** для создания эффекта «очистки», когда содержимое новой страницы поднимается снизу вверх, заменяя «старое» содержимое.
Процесс прост: для исходящей страницы мы меняем значение по умолчанию inset() на 0 0 0 0 (что создает прямоугольник по верхней, правой, нижней и левой границам страницы) и меняем значение bottom на 100%. То есть страница перемещается из top в bottom.
Входящая страница начинается с обрезки top в 100% и продолжается до 0.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: wipe-up;
}
}
html:active-view-transition-type(wipe-up)::view-transition-old(root) {
animation: wipe-out 1.4s ease forwards;
}
html:active-view-transition-type(wipe-up)::view-transition-new(root) {
animation: wipe-in 1.4s ease forwards;
}
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(0 0 100% 0);
}
}
@keyframes wipe-in {
from {
clip-path: inset(100% 0 0 0);
}
to {
clip-path: inset(0 0 0 0);
}
}
Мы могли бы с такой же легкостью сделать так, чтобы объекты удалялись справа, снизу и слева, просто изменив значения inset. Например, вот так объекты удаляются справа:
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(0 0 0 100%);
}
}
@keyframes wipe-in {
from {
clip-path: inset(0 100% 0 0);
}
to {
clip-path: inset(0 0 0 0);
}
}
Свайп вправо работает так же, как свайп вверх, за исключением того, что исходящая страница сдвигается от центра вправо. Поэтому второе значение меняется с 0 на 100%. Аналогичным образом загружаемая страница сдвигается с 100% влево на 0.
То же самое касается стирание сверху вниз:
@keyframes wipe-out {
from {
clip-path: inset(0 0 0 0);
}
to {
clip-path: inset(100% 0 0 0);
}
}
@keyframes wipe-in {
from {
clip-path: inset(0 0 100% 0);
}
to {
clip-path: inset(0 0 0 0);
}
}
Вы поняли, о чем мы!
Это немного, э-э, странно. Определенно не самая практичная вещь на свете, но она показывает, насколько далеко можно зайти с помощью переходов между представлениями.
Мы используем функции scale() и rotate() для масштабирования и поворота содержимого страницы. «Старая» страница уменьшается до 0 и поворачивается по часовой стрелке на 180deg. После этого содержимое «новой» страницы увеличивается до 1 и поворачивается против часовой стрелки на -180deg. Немного opacity добавлено для создания иллюзии движения.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: zoom-rotate;
}
}
html:active-view-transition-type(zoom-rotate)::view-transition-old(root) {
animation: zoom-rotate-out 1.4s ease forwards;
transform-origin: center;
}
html:active-view-transition-type(zoom-rotate)::view-transition-new(root) {
animation: zoom-rotate-in 1.4s ease forwards;
transform-origin: center;
}
@keyframes zoom-rotate-out {
to {
transform: scale(0) rotate(180deg);
opacity: 0;
}
}
@keyframes zoom-rotate-in {
from {
transform: scale(0) rotate(-180deg);
opacity: 0;
}
}
Этот переход гораздо менее заметен, чем предыдущий. Он мог бы быть более заметным, если бы контент, на который мы переходим, был более контрастным. Но, как вы увидите в следующем видео, фон «старой» и «новой» страниц совпадает, что обеспечивает более плавный переход.
Круг создан с помощью свойства clip-path**. Фигура рисуется от центра с помощью функции circle(), размер которой варьируется от 0 % (без размера) до 150 % (размер превышает размер содержимого), благодаря чему круг охватывает всю страницу.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: circular-wipe;
}
}
html:active-view-transition-type(circular-wipe)::view-transition-old(root) {
animation: circle-wipe-out 1.4s ease forwards;
}
html:active-view-transition-type(circular-wipe)::view-transition-new(root) {
animation: circle-wipe-in 1.4s ease forwards;
}
@keyframes circle-wipe-out {
to {
clip-path: circle(0% at 50% 50%);
}
}
@keyframes circle-wipe-in {
from {
clip-path: circle(0% at 50% 50%);
}
to {
clip-path: circle(150% at 50% 50%);
}
}
Этот код перемещает «старую» страницу с «новой» страницей из правого нижнего угла экрана в правый верхний угол — или, по сути, в любой другой угол, который мы можем выбрать, изменив значения.
Для нижнего правого угла мы настроили анимацию так, чтобы она сдвигалась на -100% по осям X и Y, отдаляясь от экрана. Затем она возвращается из противоположного угла в исходное положение на 0%. Небольшой opacity помогает сгладить переход.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: diagonal-push;
}
}
html:active-view-transition-type(diagonal-push)::view-transition-old(root) {
animation: diagonal-out 1.4s ease forwards;
}
html:active-view-transition-type(diagonal-push)::view-transition-new(root) {
animation: diagonal-in 1.4s ease forwards;
}
@keyframes diagonal-out {
to {
transform: translate(-100%, -100%);
opacity: 0;
}
}
@keyframes diagonal-in {
from {
transform: translate(100%, 100%);
opacity: 0;
}
}
Здесь как будто занавеска задергивается на «старой» странице и открывается на «новой». Это еще один пример, где в игру вступает функция inset() . Мы определяем прямоугольники, расположенные на 50 % справа и слева. При переходе на предыдущую страницу их размер увеличивается до 50 %, а при переходе на следующую — уменьшается до 0, благодаря чему изображение появляется в центре и распространяется влево и вправо, как занавеска!
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: curtain;
}
}
html:active-view-transition-type(curtain)::view-transition-old(root) {
animation: curtain-out 1.4s ease forwards;
}
html:active-view-transition-type(curtain)::view-transition-new(root) {
animation: curtain-in 1.4s ease forwards;
}
@keyframes curtain-out {
from {
clip-path: inset(0 0 0 0);
}
}
@keyframes curtain-in {
from {
clip-path: inset(0 50% 0 50%);
}
to {
clip-path: inset(0 0 0 0);
}
}
Мы как бы имитируем «переворот» одной страницы, как в двусторонней открытке, в то время как другая страница переворачивается по оси Z.
@media (prefers-reduced-motion: no-preference) {
@view-transition {
navigation: auto;
types: flip-3d;
}
}
html:active-view-transition-type(flip-3d)::view-transition-old(root) {
animation: flip-out 1.4s ease forwards;
}
html:active-view-transition-type(flip-3d)::view-transition-new(root) {
animation: flip-in 1.4s ease forwards;
}
@keyframes flip-out {
0% {
transform: rotateY(0deg) translateX(0vw);
}
100% {
transform: rotateY(-90deg) translateX(-100vw);
opacity: 1;
}
}
@keyframes flip-in {
0% {
transform: rotateY(90deg) translateX(100vw);
}
100% {
transform: rotateY(0deg) translateX(0vw);
}
}
* Правило @view-transition позволяет страницам использовать междокументные переходы. Другими словами, оно позволяет создавать анимацию между страницами одного и того же источника с помощью только CSS. Самый простой способ добиться этого — установить для дескриптора navigation значение auto на страницах, между которыми вы хотите осуществлять переходы.
@view-transition {
navigation: auto;
}
** Свойство clip-path** в CSS позволяет указать, какая часть элемента должна отображаться, а какая — скрываться (или «обрезаться»).
.clip-me {
/* Example: clip away the element from the top, right, bottom, and left edges */
clip-path: inset(10px 20px 30px 40px); /* or "none" */
/* Example: clip element into a Heptagon */
clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 0% 60%, 10% 20%);
/* Deprecated version */
position: absolute; /* absolute or fixed positioning required */
clip: rect(110px, 160px, 170px, 60px); /* or "auto" */
/* values descript a top/left point and bottom/right point */
}
*** scale(): Изменяет размер элемента. Это также относится к font-sizepadding, height и width элемента. Кроме того, это сокращенная функция для scaleX и scaleY функций.
rotate(): Поворачивает элемент по часовой стрелке относительно его текущего положения.
.element {
transform: scale(2, .5);
}
.element {
transform: rotate(25deg);
}
Если у вас есть вопросы по статье или нужна помощь в создании сайта, пишите нам в чат на сайте или Вконтакте. Не забудьте оставить свой e-mail и мы ответим в самое ближайшее время.Другие статьи по теме:
Рассмотрим в этой статье, как сделать фоновые волны на сайте, используя только возможности CSS3 и SVG файл. Т.е. без применения Javascript.
Хотим поделиться с вами несколькими CSS трюками, которые вам точно пригодятся при создании сайтов. Они позволят вам без использования Javascript создать анимацию и эффекты.
Как сделать красивую градиентную обводку блока на одном только CSS? Для этого мы сделаем следующее:
1. Создадим div.linear-gradient с градиентным фоном;
2. Создадим внутренний блок div с небольшим отступом.
Такие указатели чаще всего применяют на первом экране Главной страницы сайта, когда на ней размещена полноэкранная картинка, видео или слайдер. Чтобы показать Пользователю, что основной контент расположен ниже, в нижней части экрана размещают стрелку, направленную вниз. Чтобы привлечь к ней дополнительное внимание, её делаю анимационный...