Примеры анимации CSS псевдо-элементов before и after

Сегодня мы поэкспериментируем с анимацией и переходами CSS псевдо-элементов before и after, постараемся полностью раскрыть их потенциал. Немного поговорим об анимации псевдо-элементов before и after и рассмотрим четыре примера, которые используют специальные методы для достижения различных эффектов.

Сложность

Для начала рассмотрим преимущества и недостатки использования анимации и переходов с CSS псевдо-элементами before и after.

Преимущества

  • Упрощенная и оптимизированная HTML разметка.
  • Использование возможностей CSS3.
  • Взаимодействие с дизайном.

Недостатки

  • Имеют поддержку только современных браузеров, такие как Firefox, Internet Explorer 10 и обновленный Chrome.
  • Не работает в мобильных браузерах.
  • Псевдо-элементы  before и after не могут иметь идентификатор.
  • Псевдо-элементы before и after не используются в DOM.
  • Псевдо-элементы before и after не могут быть анимированы при помощи JavaScript.

Обратите внимание, что у псевдо-элементов before и after больше недостатков, чем преимуществ, но я думаю, что у них большое будущее!

Следующие четыре примера, мы создали именно для данной темы. Конечно, есть и другие способы для достижения таких же визуальных эффектов, но ради этого эксперимента, мы будем использовать только псевдо-элементы before и after.

Очень интересный факт: псевдо-элементы before и after наследуют свойства своего родителя. В случае анимации, все преобразования затрагивают их напрямую. Это может пригодиться, если мы хотим увеличить их поддержку в браузерах.

Пример 1

css before after

Для начала, мы создадим один забавный эффект: анимация капли воды, падающая в округлый контейнер.

HTML разметка

<div class="drop"></div>

Мы создали всего один элемент, хотя можно добавить ещё один контейнер, который будет управлять изменением масштаба.

CSS

*,
*:before,
*:after {
    box-sizing: border-box;
}
 
.drop {
    background: rgba(255, 255, 245, 1);
    border: 4px solid rgba(255, 245, 235, 1);
    border-radius: 100%;
    box-shadow: inset -0.1em 0 2em 0.5em rgba(255, 255, 255, 0.5), 
                inset -0.1em 0 0.5em 0 rgba(0, 0, 0, 0.8);
    position: relative;
    margin: 0 auto;
    width: 15em; 
    height: 15em;
    overflow: hidden;
}
 
.drop:before,
.drop:after {
    content:"";
    display:block;
    position:absolute;
}
 
/* Падение капли */
 
.drop:before {
    background: rgba(167, 217, 234, 1);
    border-radius: 100%;
     
    /* Начала падения капли */
     
    box-shadow: 0 0 0 0.1em rgba(167, 217, 234, 0.8), 
                0 0 0 0.15em rgba(167, 217, 234, 0.8), 
                0 0 0 0.2em rgba(167, 227, 234, 0.8), 
                0 0 0 0.25em rgba(167, 227, 234, 0.8), 
                0 0 0 0.3em rgba(167, 227, 234, 0.8), 
                0 0 0 0.35em rgba(167, 227, 234, 0.8), 
                0 0 0 0.4em rgba(167, 227, 234, 0.8), 
                0 0 0 0.45em rgba(167, 227, 234, 0.8), 
                0 0 0 0.5em rgba(167, 227, 234, 0.8);
    top: 0%; left: 50%;
     
    /* "width" и "height" должна быть меньше чем общий размер "box-shadow". */
     
    width: 0.2em; 
    height: 0.2em;
    animation: fall 3.5s cubic-bezier(0.5, 0, 1, 0.5) infinite;
}
 
/* Поверхность */
 
.drop:after {
    background: rgb(52, 152, 219);
    background: linear-gradient(rgba(52, 255, 255, 1) 0%, rgba(52, 152, 219, 1) 10%, rgba(152, 252, 219, 1) 100%);
    border-radius: 100% 0 50% 0;
    left: 0; 
    bottom: 0;
    width: inherit; 
    height: 3em;
    opacity: 0.7;
    animation: surface 3s linear infinite;
}
 
/* Анимация падения */
 
@keyframes fall  {
 
    /* Форма */
 
    5%, 15%  {
        box-shadow: 0 -1.4em 0 0.1em rgba(167, 217, 234, 1), 
                    0 -0.8em 0 0.15em rgba(167, 217, 234, 1), 
                    0 -0.3em 0 0.2em rgba(167, 217, 234, 1), 
                    0 -0.1em 0 0.25em rgba(167, 217, 234, 1), 
                    0 0 0 0.3em rgba(167, 217, 234, 1), 
                    0 0.2em 0 0.35em rgba(167, 217, 234, 1), 
                    0 0.4em 0 0.4em rgba(167, 217, 234, 1), 
                    0 0.6em 0 0.45em rgba(167, 217, 234, 1), 
                    0 0.8em 0 0.5em rgba(167, 217, 234, 1);
    }
     
    /* Завершение */
     
    16%  {
        top: 80%;
    }
     
    /* Контакт с поверхностью */
     
    18%  {
        top: 80%;
        box-shadow: 1em -8em 0 0.2em rgba(177, 227, 234, 1), 
                    -2.2em -3.8em 0 0.1em rgba(177, 227, 234, 1), 
                    3em -2.85em 0 0.3em rgba(177, 227, 234, 1), 
                    -3.5em -4em 0 0.2em rgba(177, 227, 234, 1), 
                    0 0 0 0.3em rgba(177, 227, 234, 1), 
                    2em -2em 0 0.2em rgba(177, 227, 234, 1), 
                    -0.3em -3em 0 0.2em rgba(177, 227, 234, 1), 
                    0.5em -5em 0 0.35em rgba(177, 227, 234, 1), 
                    -3em -1em 0 0.3em rgba(177, 227, 234, 1);
    }
     
    /* Дисперсия */
     
    30%  {
        top: 90%;
        box-shadow: 1.5em 0 0 0.2em rgba(252, 252, 255, 0.1), 
                    -2em 0 0 0.15em rgba(252, 252, 255, 0.1), 
                    3em 0 0 0.2em rgba(252, 252, 255, 0.1), 
                    -2em 0 0 0.25em rgba(252, 252, 255, 0.1), 
                    0 0 0 0.2em rgba(252, 252, 255, 0.1), 
                    2.35em 0 0 0.3em rgba(252, 252, 255, 0.1), 
                    -0.5em 0 0 0.2em rgba(252, 252, 255, 0.1), 
                    1em 0 0 0.3em rgba(252, 252, 255, 0.1), 
                    -4em 0 0 0.4em rgba(252, 252, 255, 0.1);
    }
     
    /* Скрытие */
     
    40%, 100%  {
        top: 95%;
        background: rgba(255, 255, 255, 1);
        box-shadow: 1.8em 0.5em 0 0.2em rgba(255, 255, 255, 0), 
                    -3em 0.5em 0 0.1em rgba(255, 255, 255, 0), 
                    4em 0.5em 0 0.1em rgba(255, 255, 255, 0), 
                    -3.5em 0.5em 0 0.1em rgba(255, 255, 255, 0), 
                    0 0 0 0.3em rgba(255, 255, 215, 0), 
                    2.45em 0.5em 0 0.1em rgba(255, 255, 255, 0), 
                    -0.8em 0.5em 0 0.2em rgba(255, 255, 255, 0), 
                    1.5em 0.5em 0 0.3em rgba(255, 255, 255, 0), 
                    -4.5em 0.5em 0 0.2em rgba(255, 255, 255, 0);
    }
}
 
/* Анимация воды */
 
@keyframes surface  {
    50%  {
        border-radius: 0 75% 0 75%;
        opacity: 0.5;
        height: 3.5em;
    }
}

Советую Вам поэкспериментировать с различными скоростями CSS переходов и ключевых кадров.

Давайте вернемся к нашей теме. В этом примере, псевдо-класс :before имеет такую же ширину, как и родительский элемент.

Пример 2

css before after пример

В этом примере мы создадим элемент, который будет изменяться при наведении курсора, с помощью CSS transitions.

HTML разметка

<div class="circle">
    <h1>codrops</h1>
</div>

Здесь мы используем контейнер с заголовком h1.

CSS

.circle {
    background: rgb(255,255,255);
    border-radius: 100%;
    cursor: pointer;
    position: relative;
    margin: 0 auto;
    width: 15em; 
    height: 15em;
    overflow: hidden;
    transform: translateZ(0);
}
 
.circle h1 {
    color: rgba(189, 185, 199,0);
    font-family: 'Lato', sans-serif;
    font-weight: 900;
    font-size: 1.6em;
    line-height: 8.2em;
    text-align: center;
    text-transform: uppercase;
    -webkit-font-smoothing: antialiased;
    user-select: none;
    transition: color 0.8s ease-in-out;
}
 
.circle:before,
.circle:after {
    border-radius: 100%;
    content:"";
    position: absolute;
    top: 0; 
    left: 0;
    width: inherit; 
    height: inherit;            
    box-shadow: inset 10.6em 0 0 rgba(30, 140, 209, 0.2), 
                inset 0 10.6em 0 rgba(30, 140, 209, 0.2), 
                inset -10.6em 0 0 rgba(30, 140, 209, 0.2), 
                inset 0 -10.6em 0 rgba(30, 140, 209, 0.2);
    transition: box-shadow 0.75s;
}
 
/* Мы вращаем псевдо-элемент :after чтобы получить определенный угол. */
 
.circle:after  {
    transform: rotate(45deg);
}
  
.circle:hover:before,
.circle:hover:after  {
    box-shadow: inset 0.86em 0 0 rgba(255, 0, 0, 0.5), 
                inset 0 0.86em 0 rgba(252, 150, 0, 0.5), 
                inset -0.86em 0 0 rgba(0, 255, 0, 0.5), 
                inset 0 -0.86em 0 rgba(0, 150, 255, 0.5);
}
 
.circle:hover > h1  {
    color: rgba(185, 185, 185,1);
}

Вы должны использовать только один цвет за один раз, чтобы избежать нежелательного смешивания цветов с наложением, если оно запускается при наведении мышью.

Пример 3

css before after анимация

В этом примере мы создадим анимацию загрузки как в Spinner!
Идея состоит в том, чтобы объединить несколько цветов через вращение. Это очень просто!

HTML разметка

<div class="loading"></div>

Создали один контейнер с классом loading.

CSS

.loading  {
    background: rgba(0, 50, 250, 0);
    position: relative;
    margin: 5em auto 0 auto;
    width: 3em; 
    height: 3em;
    animation-name:rotate;
}
 
.loading,
.loading:before,
.loading:after  {
    border-radius: 100%;
    animation-duration: 3s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in;
}
 
.loading:before,
.loading:after  {
    content: "";
    position: absolute;
    top: 0; 
    left: 0;
    width: inherit; 
    height: inherit;
}
 
.loading:before  {
    background: rgba(200, 250, 100, 0);
    animation-name: ring;
}
 
.loading:after  {
    background: rgba(250, 0, 200, 0);
    animation-name: ring2;
}
 
@keyframes rotate  {
    0%  {
        transform: rotateZ(0deg) scaleX(0.1) scaleY(0.1) translateZ(0);
        box-shadow: inset 0.8em 0 0 rgba(255, 0, 0, 0.5), 
                    inset 0 0.8em 0 rgba(252, 150, 0, 0.5), 
                    inset -0.8em 0 0 rgba(0, 255, 0, 0.5), 
                    inset 0 -0.8em 0 rgba(0, 150, 255, 0.5);
    }
     
    /* Скрытие */
     
    85%, 100%  {
     
    /* 360deg * 10 */
     
        transform: rotateZ(3600deg) scaleX(2.01) scaleY(2) translateZ(0);
        box-shadow: inset 0 0 0 rgba(255, 0, 0, 0), 
                    inset 0 0 0 rgba(252, 150, 0, 0), 
                    inset 0 0 0 rgba(0, 255, 0, 0), 
                    inset 0 0 0 rgba(0, 150, 255, 0);
    }
}
 
@keyframes ring  {
    0%  {
        transform: scaleX(0.1) scaleY(0.5);
        box-shadow: inset 0.8em 0 0 rgba(255, 0, 0, 0.5), 
                    inset 0 0.8em 0 rgba(252, 150, 0, 0.5), 
                    inset -0.8em 0 0 rgba(0, 255, 0, 0.5), 
                    inset 0 -0.8em 0 rgba(0, 150, 255, 0.5);
    }
     
    /* Скрытие */
     
    75%, 100%  {
        transform: scaleX(2) scaleY(2.1);
        box-shadow: inset 0 0 0 rgba(255, 0, 0, 0), 
                    inset 0 0 0 rgba(252, 150, 0, 0), 
                    inset 0 0 0 rgba(0, 255, 0, 0), 
                    inset 0 0 0 rgba(0, 150, 255, 0);
    }
}
 
@keyframes ring2  {
    0%  {
        transform: scaleX(0.5) scaleY(0.1);
        box-shadow: inset 0.8em 0 0 rgba(255, 0, 0, 0.5), 
                    inset 0 0.8em 0 rgba(252, 150, 0, 0.5), 
                    inset -0.8em 0 0 rgba(0, 255, 0, 0.5), 
                    inset 0 -0.8em 0 rgba(0, 150, 255, 0.5);
    }
     
    /* Скрытие */
     
    65%, 100%  {
        transform: scaleX(2) scaleY(2.1);
        box-shadow: inset 0 0 0 rgba(255, 0, 0, 0), 
                    inset 0 0 0 rgba(252, 150, 0, 0), 
                    inset 0 0 0 rgba(0, 255, 0, 0), 
                    inset 0 0 0 rgba(0, 150, 255, 0);
    }
}

Это отличный пример для эксперимента с таймингом и скоростью, для получения действительно плавной анимации.

Пример 4

css after before animate

Это самый сумасшедший и экстравагантный пример из всех: одноглазое летающее существо!
Мы будем использовать анимацию и переходы.

HTML разметка

<div class="pojoro"></div>

CSS

.pojoro  {
    background: rgba( 255, 255, 255, 1);
    background: radial-gradient(ellipse at center, rgba(255,255,255,1) 40%,rgba(51,51,51,1) 100%);
    border-radius: 100%;
     
    /* box-shadow: вторичный цвет, тело, ресницы */
     
    box-shadow: 0 0 0 0.2em rgb(146,89,149), 
                0 0 0.1em 0.55em rgb(176,89,179), 
                inset 0 0.2em 0 0 rgb(136,79,139);
     
    /* ojo (глаз) */
     
    color: rgba( 40, 40, 40, 0.8);
    line-height: 1.1em;
    padding-left: 0.18em;
    -webkit-font-smoothing: antialiased;
    user-select: none;
     
    /* position и transition */
     
    cursor: pointer;
    position: relative;
    margin: 5em auto 0 auto;
    width: 1em; height: 1em;
    transform-origin: center;
    transition: all 0.8s ease-in-out;
     
    /* Разделение анимации, для лучшего контроля над глазом и телом */
     
    animation: eye 2.2s ease-in-out infinite, body 1.15s 1.8s linear infinite; 
} 
 
/* Перемещение существа. */
 
.pojoro:hover  {
    transform: scaleY(0.9) scaleX(0.95) translateY(-3em) translateZ(0);
}
 
/* Крылья */
 
.pojoro:before,
.pojoro:after  {
    background: rgba(0,0,0,0);
    border-radius: 100%;
    content: "";
     
    /* display:none, скрываем крылья */
     
    display: none;
    position: absolute;
    width: 1em; height: 0.1em;
    -webkit-filter: blur(1px);
    transition: all 0.2s;
    animation-duration: 0.2s;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
}
 
.pojoro:before  {
    top: 25%; left: 1.45em;
    margin-left: -1em;
    transform-origin: left;
    transform: rotate(-60deg);
    animation-name: wings;
}
 
.pojoro:after  {
    top: 25%; left: -2.2em;
    margin-left: 1em;
    transform-origin: right;
    transform: rotate(60deg);
    animation-name: wings2;
}
 
.pojoro:hover:before,
.pojoro:hover:after  {
    background: rgba(100,100,100,0.8);
     
    /* display:block, появляются крылья, после чего начинается анимация */
     
    display: block;
    margin-left: 0em;
    width: 2em; height: 0.3em;
}
 
@keyframes eye  {
 
    /* Движение глаза */
     
    5%, 10%  {
        line-height: 1.2em;
        padding-left: 0em;
    }
    15%, 20%  {
        line-height: 1.15em;
        padding-left: 0.4em;
    }
     
    /* Движение ресниц */
     
    25%  {
        box-shadow: 0 0 0 0.2em rgb(146,89,149), 
                    0 0 0.1em 0.55em rgb(166,89,169), 
                    inset 0 1em 0 0 rgb(136,79,139);
    }
    23%, 27%  {
        box-shadow: 0 0 0 0.2em rgb(146,89,149), 
                    0 0 0.1em 0.55em rgb(166,89,169), 
                    inset 0 0.2em 0 0 rgb(136,79,139);
    }
}
 
@keyframes body  {
    50%  {
        width: 1.4em; height: 1.4em;
    } 
}
 
@keyframes wings  {
    50%  {
        transform: rotate(65deg);
    }
}
 
@keyframes wings2  {
    50%  {
        transform: rotate(-65deg);
    }
}

При наведении мы активируем анимацию крыльев и тело существа.

Псевдо-элементы before и after очень интересная вещь, комбинируя их с анимацией и переходами, можно создавать некоторые забавные эффекты без использования большого количества разметки или изображений. Я надеюсь, в ближайшее время появится более широкая поддержка этих элементов в браузерах.

ДЕМО СКАЧАТЬ

 

Перевод статьи Examples of Pseudo-Elements Animations and Transitions

Тэги: transitionanimate

Вход

Уважаемый пользователь! Мы обнаружили, что вы используете AdBlock и вынуждены скрыть часть материалов на нашем сайте. Siteacademy существует и развивается за счет доходов от рекламы. Просим внести наш сайт в список исключений или отключить Блокировщик рекламы на нашем сайте.