Иногда можно добавлять на страницу элементы с цветной анимацией просто потому что захотелось. Раньше это было очень популярно, потом стало кринжем, теперь снова можно. Воспользуемся случаем и сделаем стильную кнопку с анимированной цветной подсветкой на чистом CSS:
Логика проекта
Проект небольшой, логика тоже будет простая:
- Создаём HTML-страницу и добавляем туда кнопку стандартным способом.
- Создаём CSS-файл и пишем глобальные переменные и общие стили для всей страницы.
- Оформляем саму кнопку.
- Добавляем ей цветной кантик.
- Включаем фоновую подсветку.
- Настраиваем анимацию и действия при наведении курсора.
Выглядит несложно, за 15 минут можно успеть.
Создаём HTML-страницу
Берём стандартный шаблон пустой HTML-страницы и добавляем в него две строчки:
- В раздел
<head>
подключаем файл со стилями (его пока нет, но подключить заранее мы его всё равно можем):<link rel="stylesheet" type="text/css" href="style.css">
- В теле страницы прописываем код для кнопки, используя стандартный тег:
<button>Журнал «Код»</button>
Это всё, что нам нужно от HTML, поэтому собираем полный код, сохраняем и открываем в браузере. Там увидим одинокую кнопку в углу — это нормально, дальше всё поправим стилями.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- подключаем стили -->
<link rel="stylesheet" type="text/css" href="style.css">
<title></title>
</head>
<body>
<!-- добавляем кнопку на страницу -->
<button>Журнал «Код»</button>
</body>
</html>
Пишем базовые стили
Переходим к основной части проекта — настройке стилей. Создаём файл style.css, который мы подключили на странице, и сразу добавляем туда раздел с глобальными CSS-переменными. Они нам нужны чисто для упрощения кода, чтобы не перегружать команды шестнадцатеричными значениями цветов.
Всё это мы делаем в псевдоклассе :root
— он влияет глобально на всю страницу целиком, включая остальные элементы на ней.
/* объявляем глобальные переменные */
:root {
/* устанавливаем размер для стандартизации элементов */
--m: 4rem;
/* используемые цвета */
--red: #FF6565;
--pink: #FF64F9;
--purple: #6B5FFF;
--blue: #4D8AFF;
--green: #5BFF89;
--yellow: #FFEE55;
--orange: #FF6D1B;
}
Сразу же добавим общие настройки визуального оформления страницы: фон, тип вёрстки и отступы. Фон сделаем тёмным — так он будет более стильно сочетаться с подсветкой в будущем:
/* общие настройки страницы */
body {
/* фон */
background-color: #1C1C1C;
/* подключаем гибкую вёрстку */
display: flex;
/* выравниванием контент и содержимое по центру */
justify-content: center;
align-items: center;
/* высота — вся высота окна */
height: 100vh;
/* убираем все внешние отступы */
margin: 0;
}
Выглядит всё ещё небогато на визуал, но зато фон тёмный и кнопка уже по центру :)
Настраиваем кнопку
Так как у нас весь проект крутится вокруг кнопки, перейдём к её оформлению. Что мы сделаем:
- добавим цвет текста и его шрифт;
- настроим размер и отступы;
- добавим скругления у кнопки;
- с помощью позиционирования и гибкой вёрстки выровняем всё по центру;
- поменяем курсор, чтобы он становился другим при наведении на кнопку;
- сделаем фон для кнопки.
Единственное, на что здесь нужно обратить внимание, — это на фоновый цвет самой кнопки. Мы его сделаем градиентным и цветным в том месте, где он вылезает за границу кнопки, но визуально это пока видно не будет (пригодится на следующем шаге).
/* кнопка */
button {
/* задаём границу */
border: calc(0.08 * var(--m)) solid transparent;
/* относительное позиционирование элементов */
position: relative;
/* цвет текста */
color: #F3F3F3;
/* шрифт */
font-family: 'Space Grotesk';
/* размер шрифта */
font-size: var(--m);
/* радиус скругления кнопки */
border-radius: calc(0.7 * var(--m));
/* внутренний отступ текста от кнопки */
padding: calc(0.5 * var(--m)) calc(1 * var(--m));
/* гибкая вёрстка */
display: flex;
/* выравниваем содержимое по центру */
justify-content: center;
/* меняем курсор, который появится на кнопке */
cursor: pointer;
/* делаем фоновый градиент по границе кнопки */
background:linear-gradient(#121213, #121213), linear-gradient(#121213 50%, rgba(18, 18, 19, 0.6) 80%, rgba(18, 18, 19, 0)), linear-gradient(90deg, var(--orange), var(--yellow), var(--green), var(--blue), var(--purple), var(--pink), var(--red));
}
Теперь воспользуемся нашим фоном с градиентом, чтобы добавить кнопке красивую окантовку снизу. Для этого мы делаем эту часть фона видимой, подрезаем её немного и добавляем анимацию. Правил анимации пока нет, поэтому двигаться ничего не будет, это нормально.
Добавляем это в тот же блок со стилями для кнопки:
/* учитываем все границы и внутренние отступы для определения размера цветной окантовки */
background-origin: border-box;
/* как мы обрезаем фон */
background-clip: padding-box, border-box, border-box;
/* растягиваем фоновый градиент */
background-size: 200%;
/* включаем анимацию */
animation: animate 2s infinite linear;
Добавляем анимацию
У нас есть градиент вокруг кнопки, но мы можем сделать его движущимся, как будто изнутри работает подсветка, которая постоянно меняет цвет по всей длине. Чтобы такое получилось, добавляем в стили раскадровку для анимации: просто говорим, что нам нужно равномерно сдвигать градиент:
/* правила анимации */
@keyframes animate {
/* учитываем растяжение фона в анимации */
0% {background-position: 0}
100% {background-position: 200%}
}
Добавляем фоновую размытую подсветку
Технически у нас уже готова стильная кнопка, но зачем останавливаться, если можно навесить больше красоты и цветных градиентов?
Чтобы добавить подсветку с размытием, нам понадобится псевдокласс ::before
, который будет относиться к кнопке. Технически на странице этого элемента не будет, но он появится виртуально и будет привязан к родительскому, то есть к кнопке. Если совсем сильно упростить, можно считать, что у нас появится новый элемент перед кнопкой, с которым мы можем делать что угодно. Так вот, этим «чем угодно» здесь будет как раз наш градиент.
Создаём псевдоэлемент ::before
у кнопки:
/* псевдоэлемент, который отвечает за фоновую подсветку */
button::before {
/* добавляем пустой контент, чтобы появился блок */
content: '';
/* делаем фоновый градиент под кнопкой */
background: linear-gradient(90deg, var(--orange), var(--yellow), var(--green), var(--blue), var(--purple), var(--pink), var(--red));
/* высота и ширина градиента */
height: 30%;
width: 60%;
/* включаем абсолютное позиционирование */
position: absolute;
/* сдвигаем градиент вниз относительно кнопки */
bottom: -20%;
/* перемещаем слой с градиентом на самый низ */
z-index: -5;
/* растягиваем фоновый градиент */
background-size: 200%;
/* запускаем анимацию */
animation: animate 2s infinite linear;
/* добавляем размытие к градиенту */
filter: blur(calc(1 * var(--m)));
}
Бонус: действие при наведении курсора
Чтобы было совсем дорого-богато, сделаем так: ускорим анимацию при наведении курсора на кнопку. Так пользователь точно поймёт, что мы от него чего-то ждём (нажатия, например).
Чтобы такое реализовать, используем ещё один псевдокласс — :hover
, который срабатывает при наведении курсора на элемент. Всё, что нам там нужно прописать, — ускорение анимации, чтобы весь круг проходил всего за полсекунды.
Обратите внимание, чтобы синхронизировать анимацию между кантиком кнопки и фоновой подсветкой, нам нужно указать :hover
для двух этих элементов сразу:
/* действия при наведении мыши */
button:hover, button:hover::before {
/* ускоряем анимацию */
animation: animate 0.5s infinite linear;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- подключаем стили -->
<link rel="stylesheet" type="text/css" href="style.css">
<title></title>
</head>
<body>
<!-- добавляем кнопку на страницу -->
<button>Журнал «Код»</button>
</body>
</html>
/* объявляем глобальные переменные */
:root {
/* устанавливаем размер для стандартизации элементов */
--m: 4rem;
/* используемые цвета */
--red: #FF6565;
--pink: #FF64F9;
--purple: #6B5FFF;
--blue: #4D8AFF;
--green: #5BFF89;
--yellow: #FFEE55;
--orange: #FF6D1B;
}
/* общие настройки страницы */
body {
/* фон */
background-color: #1C1C1C;
/* подключаем гибкую вёрстку */
display: flex;
/* выравниванием контент и содержимое по центру */
justify-content: center;
align-items: center;
/* высота — вся высота окна */
height: 100vh;
/* убираем все внешние отступы */
margin: 0;
}
/* кнопка */
button {
/* задаём границу */
border: calc(0.08 * var(--m)) solid transparent;
/* относительное позиционирование элементов */
position: relative;
/* цвет текста */
color: #F3F3F3;
/* шрифт */
font-family: 'Space Grotesk';
/* размер шрифта */
font-size: var(--m);
/* радиус скругления кнопки */
border-radius: calc(0.7 * var(--m));
/* внутренний отступ текста от кнопки */
padding: calc(0.5 * var(--m)) calc(1 * var(--m));
/* гибкая вёрстка */
display: flex;
/* выравниваем содержимое по центру */
justify-content: center;
/* меняем курсор, который появится на кнопке */
cursor: pointer;
/* делаем фоновый градиент по границе кнопки */
background:linear-gradient(#121213, #121213), linear-gradient(#121213 50%, rgba(18, 18, 19, 0.6) 80%, rgba(18, 18, 19, 0)), linear-gradient(90deg, var(--orange), var(--yellow), var(--green), var(--blue), var(--purple), var(--pink), var(--red));
/* учитываем все границы и внутренние отступы для определения размера фона */
background-origin: border-box;
/* как мы обрезаем фон */
background-clip: padding-box, border-box, border-box;
/* растягиваем фоновый градиент */
background-size: 200%;
/* включаем анимацию */
animation: animate 2s infinite linear;
}
/* псевдоэлемент, который отвечает за фоновую подсветку */
button::before {
/* добавляем пустой контент, чтобы появился блок */
content: '';
/* делаем фоновый градиент под кнопкой */
background: linear-gradient(90deg, var(--orange), var(--yellow), var(--green), var(--blue), var(--purple), var(--pink), var(--red));
/* высота и ширина градиента */
height: 30%;
width: 60%;
/* включаем абсолютное позиционирование */
position: absolute;
/* сдвигаем градиент вниз относительно кнопки */
bottom: -20%;
/* перемещаем слой с градиентом на самый низ */
z-index: -5;
/* растягиваем фоновый градиент */
background-size: 200%;
/* запускаем анимацию */
animation: animate 2s infinite linear;
/* добавляем размытие к градиенту */
filter: blur(calc(1 * var(--m)));
}
/* действия при наведении мыши */
button:hover, button:hover::before {
/* ускоряем анимацию */
animation: animate 0.5s infinite linear;
}
/* правила анимации */
@keyframes animate {
/* учитываем растяжение фона в анимации */
0% {background-position: 0}
100% {background-position: 200%}
}
}