Источник: Nuances of Programming
Посетив блог на сайте shoptalkshow, я был приятно удивлен, увидев такой стиль:
По моему мнению, этот стиль уникален, особенно некоторых из рамок.
В этой статье мы увидим, как можно использовать CSS для создания эффектных границ.
Свойство CSS Border
Когда речь заходит о типе границ на сайте, первое, что приходит на ум, — это разнообразие таких границ. Наиболее часто используемые — solid (сплошная) и dashed (пунктирная). Последняя используется в приведенном выше примере.
Помимо наиболее распространенных типов границ (solid и dashed), CSS border также поддерживает стили none, hidden, dotted, double, groove, ridge, inset и outset. Кроме none и hidden, все остальные стили границ поддерживаются нативно:
Это базовые возможности. Чтобы реализовать границу другого стиля или добавить анимацию к границе, нужно использовать другие свойства и даже быть готовым к освоению новых навыков. Посмотрим, как можно разнообразить границы и сделать их более интересными.
Изменение длины границы
Начнем с простого. Научимся добавлять к границе такой эффект, который показан ниже:
Перед нами два псевдоэлемента, которые заимствуют элементы. Только верхняя и левая границы, а также нижняя и правая границы двух псевдоэлементов устанавливаются соответственно. hover, высота и ширина двух псевдоэлементов могут быть изменены при переходе.
div {
position: relative;
border: 1px solid #03A9F3;
&::before,
&::after {
content: "";
position: absolute;
width: 20px;
height: 20px;
}
&::before {
top: -5px;
left: -5px;
border-top: 1px solid var(--borderColor);
border-left: 1px solid var(--borderColor);
}
&::after {
right: -5px;
bottom: -5px;
border-bottom: 1px solid var(--borderColor);
border-right: 1px solid var(--borderColor);
}
&:hover::before,
&:hover::after {
width: calc(100% + 9px);
height: calc(100% + 9px);
}
}
https://codepen.io/Chokcoco/pen/BaLvJOb
Далее перейдем к более сложным примерам.
Анимация пунктирной границы
Используя ключевое слово dashed, можно с легкостью создавать пунктирные границы.
div {
border: 1px dashed #333;
}
Конечно, наша цель — сделать границу подвижной. Теперь мы уже не можем использовать ключевое слово dashed. Но есть много способов реализовать пунктирные линии в CSS. Например, с помощью градиентов:
div {
background: linear-gradient(90deg, #333 50%, transparent 0) repeat-x;
background-size: 4px 1px;
background-position: 0 0;
}
Пунктирные линии, смоделированные с помощью градиентов, выглядят следующим образом:
Нам доступно несколько градиентов. Мы можем использовать их для представления всех четырех сторон контейнера:
div {
background:
linear-gradient(90deg, #333 50%, transparent 0) repeat-x,
linear-gradient(90deg, #333 50%, transparent 0) repeat-x,
linear-gradient(0deg, #333 50%, transparent 0) repeat-y,
linear-gradient(0deg, #333 50%, transparent 0) repeat-y;
background-size: 4px 1px, 4px 1px, 1px 4px, 1px 4px;
background-position: 0 0, 0 100%, 0 0, 100% 0;
}
Вот эффект на выходе:
Итак, на данный момент анимация пунктирной границы выполнена более чем наполовину. Анимация border-style: dashed не поддерживается, зато можно использовать градиенты. Мы добавляем эффект hover, а после добавления animation мы можем изменить элемент background-position.
div:hover {
animation: linearGradientMove .3s infinite linear;
}
@keyframes linearGradientMove {
100% {
background-position: 4px 0, -4px 100%, 0 -4px, 100% 4px;
}
}
Взгляните на получившийся эффект: при наведении на границу она начинает двигаться. Поскольку вся анимация соединена непрерывной линией, бесконечный ее цикл выглядит так, будто пунктирная граница движется все время. В этом и есть наш маленький секрет.
Поделюсь еще одним хитрым трюком. Чтобы происходил переход одного вида границы к пунктирной границе и затем наступал эффект анимации, можно использовать только градиенты. Вот пример такого кода:
div {
border: 1px solid #333;
&:hover {
border: none;
background:
linear-gradient(90deg, #333 50%, transparent 0) repeat-x,
linear-gradient(90deg, #333 50%, transparent 0) repeat-x,
linear-gradient(0deg, #333 50%, transparent 0) repeat-y,
linear-gradient(0deg, #333 50%, transparent 0) repeat-y;
background-size: 4px 1px, 4px 1px, 1px 4px, 1px 4px;
background-position: 0 0, 0 100%, 0 0, 100% 0;
}
}
Из-за разницы в положении границы и фона на модели блока будет наблюдаться очевидное визуальное несоответствие:
Чтобы исправить это, можно заменить border на outline, потому что outline можно установить на outline-offset. Это идеальное решение проблемы:
div {
outline: 1px solid #333;
outline-offset: -1px;
&:hover {
outline: none;
}
}
Посмотрите на эффект, который мы применили к кнопке:
Полный код вышеуказанной демонстрации находится здесь:
https://codepen.io/Chokcoco/pen/NWRevaJ
Другие способы использования градиентов
С помощью градиентов можно добиться не только вышеперечисленных эффектов.
Продолжим исследовать возможности этого инструмента. С его помощью можно, например, сделать интересный фон:
div {
position: relative;
&::after {
content: '';
position: absolute;
left: -50%;
top: -50%;
width: 200%;
height: 200%;
background-repeat: no-repeat;
background-size: 50% 50%, 50% 50%;
background-position: 0 0, 100% 0, 100% 100%, 0 100%;
background-image: linear-gradient(#399953, #399953), linear-gradient(#fbb300, #fbb300), linear-gradient(#d53e33, #d53e33), linear-gradient(#377af5, #377af5);
}
}
Обратите внимание: здесь используется графика, созданная псевдоэлементом используемого элемента. Ширина и высота родительского элемента такие же (200%), как у родительского элемента overflow: hidden.
Добавим эффект вращения:
div {
animation: rotate 4s linear infinite;
}
@keyframes rotate {
100% {
transform: rotate(1turn);
}
}
Вот что получилось:
Наконец, используйте псевдоэлемент для маскировки середины, и получится красивая анимация границы (будут появляться полупрозрачные элементы):
Полный код приведен ниже.
https://codepen.io/Chokcoco/pen/NWRevaJ
Изменение цвета градиента
После освоения вышеперечисленных базовых навыков мы можем внести некоторые коррективы в цвета градиента, превратив 4 цвета в 1:
div::after {
content: '';
position: absolute;
left: -50%;
top: -50%;
width: 200%;
height: 200%;
background-color: #fff;
background-repeat: no-repeat;
background-size: 50% 50%;
background-position: 0 0;
background-image: linear-gradient(#399953, #399953);
Получаем такую картину:
Теперь добавим эффект прокрутки. Получится такая одноцветная анимация движущейся границы:
Выглядит красиво. Однако в случае одной линии появляется очевидный дефект. Края границы представляют собой маленькие треугольники вместо прямых углов, что может быть неприменимо в некоторых сценариях или неприемлемо для менеджера проекта:
Можно ли избавиться от этих маленьких треугольников? Да, ниже мы рассмотрим метод, использующий clip-path и устраняющий эту проблему.
Conic-gradient
Прежде чем мы разберемся с clip-path, поговорим об угловых градиентах.
В вышеупомянутых случаях в основном используются линейные градиенты (linear-gradient). Но мы можем применять и конический градиент (conic-gradient).
Попробуем использовать conic-gradient. На этот раз постараемся сделать темный стиль. Основной код выглядит следующим образом:
.conic {
position: relative;
&::before {
content: '';
position: absolute;
left: -50%;
top: -50%;
width: 200%;
height: 200%;
background: conic-gradient(transparent, rgba(168, 239, 255, 1), transparent 30%);
animation: rotate 4s linear infinite;
}
}
@keyframes rotate {
100% {
transform: rotate(1turn);
}
}
Рендеринг и схематические диаграммы показаны ниже. Мы поворачиваем граф с частичным угловым градиентом и используем другой псевдоэлемент для маскировки середины, чтобы видна была только линейная часть:
https://codepen.io/Chokcoco/pen/dypaobm
Clip-path
Возвращаемся к свойству clip-path. С ним анимация становится еще интереснее.
С помощью этого свойства можно анимировать саму точку координат, производя преобразования из одной отсеченной области в другую.
Используя clip-path, мы можем реализовать интересный эффект границы, показанный ниже. Псевдокод выглядит следующим образом:
div {
position: relative;
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 2px solid gold;
animation: clippath 3s infinite linear;
}
}
@keyframes clippath {
0%,
100% {
clip-path: inset(0 0 95% 0);
}
25% {
clip-path: inset(0 95% 0 0);
}
50% {
clip-path: inset(95% 0 0 0);
}
75% {
clip-path: inset(0 0 0 95%);
}
}
Рендеринг и схематическая диаграмма:
Поскольку в этом случае элементы будут отсечены, псевдоэлементы можно использовать в качестве фона для обрезки и анимации. К тому же на обрезанной границе не будут возникать маленькие треугольники. Этот метод также поддерживает возможность закругления границ (border-radius).
Если использовать другой псевдоэлемент для реализации стиля кнопки, можно получить такой эффект:
https://codepen.io/Chokcoco/pen/dypayrM
Свойство overflow
В следующем приеме задействуется свойство overflow. Реализуйте такую анимацию границы:
Почему же здесь реализуется overflow?
Вставьте диаграмму:
https://codepen.io/Chokcoco/pen/PooBpQe
Обратим внимание на два основных момента.
- Мы используем overflow: hidden, чтобы скрыть весь элемент, который изначально был вне контейнера.
- transform-origin управляет центром вращения элемента.
Как вы уже заметили, для создания большинства интересных CSS-эффектов используются похожие приемы.
Проще говоря, анимация, которую мы видим, — это лишь малая часть первоначального явления. С помощью специального обрезания, изменения прозрачности, масок и других средств мы видим только часть исходного явления.
Border-image
Применяя border-image, мы также можем добиться интересной анимации границ. Предположим, у нас есть такой шаблон:
Вы можете использовать свойства border-image-slice и border-image-repeat для получения похожего рисунка границы:
div {
width: 200px;
height: 120px;
border: 24px solid;
border-image: url(image-url);
border-image-slice: 32;
border-image-repeat: round;
}
Высота и ширина элемента могут быть изменены по желанию, так что он может быть расширен до любого размера границы контейнера:
https://codepen.io/Chokcoco/pen/oNzJeKd
Отличие от примера выше заключается в том, что мы должны заставить паттерн двигаться, то есть нужно получить такое фоновое изображение:
Затем мы также можем получить карту движущейся границы. Код будет точно таким же, но граница движется:
https://codepen.io/Chokcoco/pen/XWjEgRq
Border-image и градиенты
Можно использовать не только текстовые ссылки url. Непосредственная заливка цветов и градиентов также допускается.
С помощью border-image, filter и clip-path можно получить закругленную границы с градиентным преобразованием:
.border-image-clip-path {
width: 200px;
height: 100px;
border: 10px solid;
border-image: linear-gradient(45deg, gold, deeppink) 1;
clip-path: inset(0px round 10px);
animation: huerotate 6s infinite linear;
filter: hue-rotate(360deg);
}
@keyframes huerotate {
0% {
filter: hue-rotate(0deg);
}
100% {
filter: hue-rotate(360deg);
}
}
https://codepen.io/Chokcoco/pen/povBORP
- Демо-версия применения clip-path, border-image и filter для получения закругленных градиентных границ на CodePen.
Читайте также:
Перевод статьи ChokCoco: Fantastic CSS border animation