Посетив блог на сайте 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);
    }
}
  • Демо-версия анимации по ширине границы на CodePen.

Далее перейдем к более сложным примерам.

Анимация пунктирной границы

Используя ключевое слово 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;
}
}

Посмотрите на эффект, который мы применили к кнопке:

Полный код вышеуказанной демонстрации находится здесь:

  • Демо-версия анимации пунктирной границы на CodePen.

Другие способы использования градиентов

С помощью градиентов можно добиться не только вышеперечисленных эффектов.

Продолжим исследовать возможности этого инструмента. С его помощью можно, например, сделать интересный фон:

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);
    }
}

Вот что получилось:

Наконец, используйте псевдоэлемент для маскировки середины, и получится красивая анимация границы (будут появляться полупрозрачные элементы):

Полный код приведен ниже.

  • Демо-версия анимации границы с помощью градиентов на CodePen.

Изменение цвета градиента

После освоения вышеперечисленных базовых навыков мы можем внести некоторые коррективы в цвета градиента, превратив 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);

Получаем такую картину:

Теперь добавим эффект прокрутки. Получится такая одноцветная анимация движущейся границы:

  • Еще одна демо-версия анимации границы с помощью градиентов на CodePen.

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

Можно ли избавиться от этих маленьких треугольников? Да, ниже мы рассмотрим метод, использующий 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);
}
}

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

  • Демо-версия вращающейся границы на CodePen.

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%);
    }
}

Рендеринг и схематическая диаграмма:

  • Демо-версия анимации границы с помощью clip-path на CodePen.

Поскольку в этом случае элементы будут отсечены, псевдоэлементы можно использовать в качестве фона для обрезки и анимации. К тому же на обрезанной границе не будут возникать маленькие треугольники. Этот метод также поддерживает возможность закругления границ (border-radius).

Если использовать другой псевдоэлемент для реализации стиля кнопки, можно получить такой эффект:

  • Еще одна демо-версия анимации границы с помощью clip-path на CodePen.

Свойство overflow

В следующем приеме задействуется свойство overflow. Реализуйте такую анимацию границы:

Почему же здесь реализуется overflow?

Вставьте диаграмму:

  • Демо-версия использования overflow и transform для достижения линейного ховер-эффекта на CodePen.

Обратим внимание на два основных момента.

  • Мы используем 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;
}

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

  • Демо-версия border-image на CodePen.

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

Затем мы также можем получить карту движущейся границы. Код будет точно таким же, но граница движется:

  • Демо-версия границы “Танцующие черепа” на CodePen.

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);
    }
}
  • Демо-версия применения clip-path, border-image и filter для получения закругленных градиентных границ на CodePen.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи ChokCoco: Fantastic CSS border animation

Предыдущая статьяПокрытие кода в Rust
Следующая статьяAirtable: рецепт молниеносного создания баз данных и таблиц