Как использовать CSS ::before и ::after для анимаций и переходов
Вы будете удивлены, узнав, что большинство сложных дизайнов, которые вы видите каждый день, были созданы с помощью простого ванильного CSS с использованием мощи псевдоэлементов. В этой статье мы рассмотрим, как использовать эти псевдоэлементы для создания ошеломляющих эффектов.
Мы узнаем о псевдоэлементах — в частности, о псевдоэлементах ::before и ::after — и о том, как мы можем использовать их, чтобы создавать ошеломляющие анимированные переходы. Мы начнем с создания простой, но креативной анимированной кнопки, чтобы познакомится с псевдоэлементами, а затем углубимся дальше, создав анимированную карточку профиля, которая демонстрирует истинную силу псевдоэлементов.
Зачем использовать анимацию?
Содержание статьи:
Анимации создают микровзаимодействия между пользователями и вашим сайтом. Может быть довольно сложно привлечь внимание пользователя, но хорошо продуманная и удачно расположенная анимация может привлечь пользователей, заинтересовав их содержанием вашего веб-сайта.
Крутые анимации также оживляют простой на вид дизайн интерфейса, а также помогают улучшить взаимодействие с пользователем, когда они разработаны с учетом действий пользователя, обеспечивая визуальную обратную связь.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Предпосылки
Прежде чем переходить к самой интересной части, мы должны рассмотреть некоторые основы, чтобы ознакомиться со всем необходимым для работы нашей анимации.
Что такое псевдоэлементы?
Псевдоэлементы — это селекторы CSS, используемые для вставки искусственного или декоративного содержимого (т. е. содержимого, которого нет в фактической разметке HTML) и для стилизации определенных частей элемента. Существует несколько псевдоэлементов, таких как ::before, ::after, ::placeholder, ::first-letter и т. д. Но в этой статье мы сосредоточимся только на двух, ::before и ::after.
Псевдоэлемент ::before
Псевдоэлемент ::before вставляет некоторый контент перед элементом.
CSS h1::before { content: “your smile”; }
123 | h1::before { content: “your smile”;} |
Результатом вышеизложенного будет:
Псевдоэлемент ::after
Псевдоэлемент ::after используется для вставки содержимого после содержимого элемента.
CSS h1::after { content: “your smile”; }
123 | h1::after { content: “your smile”;} |
Точно также вывод вышеприведенного будет:
В чем разница между псевдоэлементами и псевдоклассами?
Псевдоэлементы иногда путают с псевдоклассами, потому что они выглядят и звучат одинаково, но на самом деле это не так.
В отличие от псевдоэлементов, которые используются для вставки контента, псевдоклассы — это просто селекторы, которые нацелены на состояние элемента, а также на некоторые другие вещи. Типичным примером является селектор псевдокласса состояния :hover для элемента, который указывает, что вы хотите применить определенные правила CSS, когда пользователь наводит курсор на элемент.
Также стоит отметить, что псевдоэлемент объявляется с двумя двоеточиями, т. е. ::, а псевдокласс объявляется с одним двоеточием, т. е. :.
Анимация с псевдоэлементами
Прежде чем мы сможем перейти непосредственно к разделу статьи с проектами, мы должны уточнить некоторые вещи. Давайте удостоверимся, что у нас есть общее представление о некоторых свойствах CSS, которые делают возможной анимацию с помощью CSS:
transform (translate, rotate, scale, skew)
transition
positioning
z-index
Я предполагаю, что вы, вероятно, знакомы с большинством из них, если не со всеми, но на всякий случай мы их бегло рассмотрим.
Знакомство с Transform и Transition CSS
В нашем проекте мы будем использовать свойства CSS Transform и Transition, поэтому важно, чтобы у вас было общее представление о том, что они из себя представляют и как они работают.
Свойство CSS Transform в основном позволяет вам перемещать, вращать, масштабировать и наклонять элемент.
CSS .box-1 { transform: translate(100px, 100px); } .box-2 { transform: rotate(60deg); } .box-3 { transform: scale(2); } .box-4 { transform: skew(-30deg); }
123456789101112 | .box-1 { transform: translate(100px, 100px);}.box-2 { transform: rotate(60deg);}.box-3 { transform: scale(2);}.box-4 { transform: skew(-30deg);} |
Свойство transition позволяет вам установить продолжительность этих изменений от одного состояния к другому, чтобы сгладить весь процесс анимации.
Позиционирование с помощью свойств relative и absolute
Существует несколько свойств CSS, которые помогают вам легко управлять расположением элемента в HTML-документе, но в этой статье мы рассмотрим только свойства относительного и абсолютного расположения.
Относительное расположение
Установка относительного положения элемента позволяет вам управлять положением элемента относительно расположения других элементов страницы. Например, вы можете переместить элемент и использовать то место, где он был бы по умолчанию, в качестве точки отсчета. Приведу пример:
CSS .box-2 { position: relative; right: 150px; top: 0; }
12345 | .box-2 { position: relative; right: 150px; top: 0;} |
Как видите, второе поле смещается вправо на 150 пикселей от исходного положения, что не влияет на естественный порядок расположения элементов на странице, поскольку предыдущее пространство, которое оно занимало, учитывается окружающими элементами.
Абсолютное положение
С другой стороны, при установке абсолютной позиции элемента, CSS извлекает элемент из естественного порядка расположения элементов (заставляя его перекрывать другие элементы) и использует предоставленную координату, чтобы попытаться поместить этот элемент в родительский контейнер, чья позиция была установлена как relative.
Когда элементу не удается найти ни одного родителя, он использует тело документа в качестве относительной точки отсчета. Пример:
CSS .parent-container { position: relative; } .box-1 { position: absolute; left: 20px; top: 20px; } .box-2 { position: absolute; right: 50px; bottom: 40px; }
123456789101112131415 | .parent-container { position: relative;} .box-1 { position: absolute; left: 20px; top: 20px;} .box-2 { position: absolute; right: 50px; bottom: 40px;} |
Как и следовало ожидать, родительский контейнер становится относительной точкой отсчета для позиционирования его абсолютных дочерних элементов с использованием предоставленных координат.
Управление порядком размещения элементов с помощью z-index
Свойство z-index позволяет размещать элементы друг над другом в контексте размещения на странице. Если элемент имеет более высокий порядок стека, он всегда будет отображаться перед элементом с более низким порядком стека. Пример:
CSS .box-1 { z-index: 1; } .box-2 { z-index: 2; } .box-3 { z-index: 3; } .box-4 { z-index: 4; }
123456789101112 | .box-1 { z-index: 1;}.box-2 { z-index: 2;}.box-3 { z-index: 3;}.box-4 { z-index: 4;} |
Также стоит отметить, что z-index работает только с элементами, которые были позиционированы с помощью свойства position. Если два элемента имеют одинаковый z-index, тот, который отображается последним в разметке HTML, остается наверху. Теперь, когда мы рассмотрели основы, давайте перейдем к нашему стартовому проекту.
Создание анимированной кнопки с помощью псевдоэлемента
Для первого нашего проекта мы начнем с создания простой анимированной кнопки, чтобы понять, как использовать псевдоэлементы для анимации. Затем мы перейдем к более сложному проекту. Мы начнем с создания тега привязки в HTML-макете, который позже применим к кнопке.
<a href=”#” class=”btn”>Hover Me</a>
1 | <a href=”#” class=”btn”>Hover Me</a> |
Вот наш результат:
Давайте перейдем к файлу CSS и стилизуем эту ссылку, чтобы она выглядела как обычная кнопка.
CSS .btn { text-decoration: none; border: 2px solid #764abc; color: #764abc; padding: 10px 20px; border-radius: 25px; transition: all 1s; position: relative; }
123456789 | .btn { text-decoration: none; border: 2px solid #764abc; color: #764abc; padding: 10px 20px; border-radius: 25px; transition: all 1s; position: relative;} |
Код не требует пояснений — мы убрали подчеркивание по умолчанию, добавили сплошную границу в 2 пикселя и сделали цвет кнопки таким же, как текст. Мы также добавили отступы, чтобы оставить некоторое пространство между текстом и границей, и добавили радиус границы, чтобы изогнуть края кнопки.
Наконец, мы добавили продолжительность перехода в 1 секунду — т. е. любое изменение, которое происходит с этой кнопкой, должно происходить плавно и анимироваться в течение секунды; также мы установили относительное позиционирование, потому что собираемся поместить псевдоэлемент внутри этой кнопки.
Помните, что для позиционирования дочернего элемента с абсолютной позицией, позиционирование родительского контейнера должно быть относительным? Кнопка и будет родительским контейнером. Ниже наш результат:
Теперь, создадим псевдоэлемент этой кнопки.
CSS .btn::before { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #764abc; transition: all 1s; }
12345678910 | .btn::before { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #764abc; transition: all 1s;} |
Мы создали псевдоэлемент с пустым свойством content, что гарантирует, что внутри него ничего не размещено. Устанавливаем псевдоэлементу позицию absolute, что удаляет его из естественного порядка размещения элементов (заставляя его перекрывать кнопку), а затем устанавливаем координаты top и left равными 0, что прикрепляет пустой псевдоэлемент к кнопке в нужном месте.
После этого, мы устанавливаем ширину и высоту равными 100 процентам родительского элемента, делая его того же размера, что и сама кнопка.
Наконец, делаем фон псевдоэлемента того же цвета, что и кнопка, и еще раз добавляем переход в 1 секунду. Ниже приведен результат:
Как видите, псевдоэлемент перекрывает кнопку, потому что мы использовали абсолютную позицию. Чтобы решить эту проблему, мы должны использовать свойство z-index, чтобы изменить контекст стека, переместив псевдоэлемент позади кнопки, используя отрицательное значение. Затем мы воспользуемся свойством translate, чтобы переместить псевдоэлемент влево на -100%.
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
CSS .btn::before { /*…previous code */ z-index: -1; transform: translateX(-100%); }
12345 | .btn::before { /*…previous code */ z-index: -1; transform: translateX(-100%);} |
Теперь мы анимируем псевдоэлемент, чтобы он возвращался в исходное положение, когда мы наводим курсор на кнопку, используя псевдокласс :hover.
CSS .btn:hover::before { transform: translateX(0); }
123 | .btn:hover::before { transform: translateX(0);} |
Выше мы писали, что когда кто-то наводит курсор на кнопку, наш псевдоэлемент должен вернуться в исходное абсолютное положение. Вот наш результат:
Однако текст по-прежнему скрыт, потому что и текст и псевдоэлемент имеют одинаковый цвет. Давайте изменим цвет текста, чтобы он отображался белым при наведении курсора на кнопку.
CSS .btn:hover { color: #fff; }
123 | .btn:hover { color: #fff;} |
Поскольку мы добавили свойство translate к кнопке, изменение произойдет плавно. На последнем шаге мы применим свойство overflow:hidden к кнопке, чтобы скрыть любой элемент, выходящий за пределы контейнера. Применительно к кнопке – это скроет псевдоэлемент и покажет его только тогда, когда он вернется в исходное положение.
CSS .btn { /*…previous code. */ overflow: hidden; }
1234 | .btn { /*…previous code. */ overflow: hidden;} |
Окончательный результат:
Вот оно! Мы успешно создали красиво анимированную кнопку с помощью псевдоэлементов. Вы можете найти полный исходный код в конце этой статьи.
Создание расширенной анимированной карточки профиля с использованием нескольких псевдоэлементов
Теперь создадим более сложную анимированную карточку профиля, используя несколько псевдоэлементов, а точнее — четыре, для создания действительно потрясающего эффекта наведения. Без дальнейших церемоний, давайте перейдем непосредственно к HTML-разметке.
<div class=”profile-card”> <div class=”info”> <h2>John Doe</h2> <p>Ceo / Founder</p> </div> </div>
123456 | <div class=”profile-card”> <div class=”info”> <h2>John Doe</h2> <p>Ceo / Founder</p> </div></div> |
Мы создали простую карточку div, содержащую биографию пользователя (состоящую из имени и должности):
Давайте перейдем к файлу CSS и стилизуем эту карточку.
CSS .profile-card { width: 300px; height: 400px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); display: grid; place-items: center; position: relative; background: url(“/image.jpg”) no-repeat center center/cover; }
12345678910 | .profile-card { width: 300px; height: 400px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); display: grid; place-items: center; position: relative; background: url(“/image.jpg”) no-repeat center center/cover;} |
Мы создали карточку с фиксированной шириной/высотой, поместили содержимое внутри по центру с помощью CSS Grid и добавили тень, чтобы карточка выглядела более реалистично. Наконец, мы установили позиционирование карты как relative, чтобы сделать ее родительским контейнером для псевдоэлементов, и добавили фоновое изображение по центру. Давайте посмотрим на результат:
С этим покончено, давайте приступим к созданию псевдоэлементов. Это сложная часть. Мы намерены использовать четыре псевдоэлемента, но каждый элемент может иметь только один псевдоэлемент ::before и один псевдоэлемент ::after соответственно. Чтобы обойти это, мы будем использовать саму карточку для создания двух псевдоэлементов, а затем использовать info div внутри карточки для создания еще двух. Начнем с info div.
CSS .info::before { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; transform: skew(30deg) translateX(100%); opacity: 0.3; z-index: -1; transition: all 0.6s ease; }
12345678910111213 | .info::before { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; transform: skew(30deg) translateX(100%); opacity: 0.3; z-index: -1; transition: all 0.6s ease;} |
Теперь, поскольку сам info div не имеет фиксированной ширины или высоты, псевдоэлемент принимает полную ширину и высоту родительской карточки, делая его того же размера, что и карточка.
Затем мы наклоняем его на 30 градусов. Это смещает info div вправо. Отрицательный индекс гарантирует, что он останется за текстом, а непрозрачность сделает его полупрозрачным.
Переходим ко второму псевдоэлементу:
CSS .info::after { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; transform: skew(-30deg) translate(90%); box-shadow: 0 0 20px rgba(0, 0, 0, 0.7); opacity: 0.3; z-index: -1; transition: all 0.6s ease; }
1234567891011121314 | .info::after { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; transform: skew(-30deg) translate(90%); box-shadow: 0 0 20px rgba(0, 0, 0, 0.7); opacity: 0.3; z-index: -1; transition: all 0.6s ease;} |
Мы сделали в основном то же самое, что и псевдоэлемент ::before, но затем изменили направление наклона на противоположное и добавили тень box-shadow, чтобы тени добавлялись к сторонам, делая его более похожим на 3D.
Теперь сделаем так, чтобы при наведении на карту, псевдоэлементы продвигались дальше вглубь нее. Вы можете быть уверены, что это произойдет гладко, потому что мы добавили transition к псевдоэлементам.
CSS .profile-card:hover .info::before { transform: skew(30deg) translateX(50%); } .profile-card:hover .info::after { transform: skew(-30deg) translateX(40%); opacity: 0.7; }
1234567 | .profile-card:hover .info::before { transform: skew(30deg) translateX(50%);}.profile-card:hover .info::after { transform: skew(-30deg) translateX(40%); opacity: 0.7;} |
Теперь давайте создадим еще два псевдоэлемента, используя саму карточку.
CSS .profile-card::before { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; opacity: 0.3; transform: skew(30deg) translate(100%); transition: all 0.6s ease; z-index: -1; }
12345678910111213 | .profile-card::before { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; opacity: 0.3; transform: skew(30deg) translate(100%); transition: all 0.6s ease; z-index: -1;} |
К этому моменту этот код должен быть не требующим пояснений; мы просто сделали то же самое, что и выше, но на этот раз сместили псевдоэлемент карты ::before вправо на 85 процентов:
Создадим последний псевдоэлемент и наклоним его в направлении, противоположном направлению ::before.
CSS .profile-card::after { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; opacity: 0.3; transform: skew(-30deg) translate(85%); transition: all 0.6s ease; z-index: -1; }
12345678910111213 | .profile-card::after { content: “”; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #764abc; opacity: 0.3; transform: skew(-30deg) translate(85%); transition: all 0.6s ease; z-index: -1;} |
Как вы уже догадались, мы также сделаем так, чтобы при наведении на карточку профиля эти вновь созданные псевдоэлементы перемещались, как и предыдущие два. Но на этот раз мы сдвинем их еще дальше, чем два предыдущие.
CSS .profile-card:hover:before { transform: skew(30deg) translateX(30%); } .profile-card:hover:after { transform: skew(-30deg) translateX(20%); }
123456 | .profile-card:hover:before { transform: skew(30deg) translateX(30%);}.profile-card:hover:after { transform: skew(-30deg) translateX(20%);} |
Как видите, наша карточка профиля собирается вместе. Для последней части головоломки мы установим для свойства карты overflow значение hidden, чтобы скрыть переполняющие части.
CSS .profile-card { /*…previous code. */ overflow: hidden; }
1234 | .profile-card { /*…previous code. */ overflow: hidden;} |
Наконец, мы изменим цвет текста на белый и сделаем так, чтобы его непрозрачность была полностью прозрачной, но при наведении курсора на карточку мы вернем непрозрачность обратно в нормальное состояние, сделав текст видимым.
CSS .info h2, .info p { color: #fff; opacity: 0; transition: all 0.6s; } .profile-card:hover .info h2, .profile-card:hover .info p { opacity: 1; }
12345678910 | .info h2, .info p { color: #fff; opacity: 0; transition: all 0.6s;} .profile-card:hover .info h2,.profile-card:hover .info p { opacity: 1;} |
Конечный результат:
Исходный код (CodePen): анимированная кнопка, карточка профиля.
Заключение
Поздравляю, что дошли до конца. Как видите, псевдоэлементы ::before и ::after можно использовать несколькими способами для создания интересных анимационных эффектов, которые оживляют наши проекты.
Вы можете изучить их подробнее, чтобы создать еще более сложный дизайн и анимацию, так как с помощью псевдоэлементов ::before и ::after CSS можно сделать гораздо больше, а мы только поверхностно коснулись их применения.
Автор: David Herbert
Источник: webformyself.com