Анимация border в CSS

Анимация border в CSS

От автора: как делается анимация border CSS по состоянию hover? Просто, так ведь? Вы удивитесь. Задача проста – создать кнопку с расширяющейся рамкой при наведении мыши. В сегодняшней статье обсудим реальные CSS советы, которые легко внедрить в любой проект без вмешательства в DOM и подключения JS. Описываемые методы следуют следующим правилам.

Один элемент (без вспомогательных div, псевдоэлементы использовать можно)

Только CSS (без JS)

Работа при любом размере (без ограничения по ширине, высоте и соотношению сторон)

Поддержка прозрачных фонов

Плавный и быстрый переход

Метод 1: анимация border

Самый простой способ анимировать рамку… это анимировать свойство border.

Красиво и просто, но производительность сильно хромает.

Так как border занимает место в макете документа, то изменение border-width вызовет изменение макета. Окружающие элементы сдвинутся от элемента из-за нового размера рамки, что заставляет браузер заново вычислять позиции элементов каждый кадр анимации, если у кнопки не заданы явные размеры.

Перестройка макета не самое плохое, ведь плавный переход «отрывистый». В следующем примере я покажу вам это.

Метод 2: улучшенный border с outline

Как изменить рамку без перестройки макета? С помощью outline! Скорее всего, вы знакомы с outline (удаляете outline по :focus (не стоит этого делать)). Однако outline это внешняя линия, не меняющая размеры и положение элементов в макете.

Если заглянуть в панель разработчика в браузере на вкладку Performance, можно увидеть, что outline не вызывает перестройку макета. Тем не менее, движения все еще выглядят отрывистыми, так как браузеры округляют значения border-width и outline-width, чтобы не было рендера меньше пикселя (между 5 и 6) и плавных переходов между 5.4 и 5.5.

Странно, но Safari часто не рендерит переход outline и оставляет непонятные артифакты.

Анимация border в CSS

Метод 3: кадрирование через clip-path

Steve Gardner создал этот метод. Метод использует clip-path и calc для обрезания рамки вовнутрь. При наведении мыши мы можем показывать полную ширину рамки.

Техника с clip-path самая плавная и быстрая, но у нее есть несколько минусов. Ошибки округления могут вызвать небольшие неровности на определенных размерах. Изначально ширина рамки полная, из-за чего возникают сложности с позиционированием.

К сожалению, в IE/Edge до сих пор поддержки нет, однако она в разработке. Вы можете и обязаны поддержать команду Microsoft, проголосовав за добавление masks/clip-path.

Метод 4: фон linear-gradient

Рамку можно имитировать с помощью хитрой комбинации нескольких фонов linear-gradient с правильными размерами. Необходимо 4 отдельных градиента, по одному на сторону. Свойства background-position и background-size устанавливают все градиенты в правильное место и размеры, а их уже можно плавно менять и расширять рамку.

Метод немного сложный и немного различается в браузерах. Firefox и Safari плавно анимируют faux-border, что нам и нужно. В Chrome анимация дерганая и еще более отрывистая чем в outline и border. IE и Edge вообще отказываются анимировать background, зато эти браузеры правильно задают размеры рамки.

Метод 5: имитация через box-shadow

В спецификации box-shadow скрыто четвертое значение spread-radius. Установите все остальные значения в 0px и создайте рамку через spread-radius. Свойство, как и outline, не влияет на макет.

Переход box-shadow довольно быстрый и намного плавнее. Исключение Safari – браузер привязывается к целым значениям во время переходов свойств border и outline.

Псевдоэлементы

Несколько техник можно изменить под псевдо-элементы, однако псевдо-элементы вызывают проблемы с производительностью.

В случае с методом box-shadow плавный переход иногда вызывает перерисовку большей области, чем необходимо. Reinier Kaper заметил, что псевдоэлементы могут изолировать отрисовку на большую область. Дополнительные тесты выявили, что box-shadow больше не вызывает отрисовку на больших областях документа, а сложность псевдоэлементов снижает производительность. Изменения в отрисовке и производительности могли быть вызваны обновлением Chrome, можете сами проверить.

Я также не нашел способа, как с помощью псевдоэлементов использовать transform анимацию.

А почему не transform: scale?

Можете обратиться в Twitter и предложить transform: scale. Свойства transform и opacity лучше всего анимируются по скорости, так почему не использовать псевдоэлемент и менять размер рамки?

Есть несколько проблем:

Рамка будет видна через прозрачную кнопку. Я специально убрал фон кнопки, чтобы показать, как рамка прячется под кнопкой. Если в вашем дизайне кнопки с фоном, то все будет нормально.

Можно масштабировать рамку до определенного размера. Размеры кнопки могут меняться в зависимости от текста, поэтому нет четкого способа анимировать рамку от 5px до 10px через CSS. В этом примере я добавил немного магии в scale, но пример не универсален.

Рамка анимируется неровно из-за того, что соотношение сторон у кнопки не 1:1. То есть left/right будут больше, чем top/bottom, пока анимация не завершится. Проблема может быть не заметна на большой скорости анимации, правильном соотношении сторон кнопки и размерах рамки.

Если у вашей кнопки заданы размеры, Cher нашла умный способ вычисления точного масштаба. Однако могут возникнуть некоторые ошибки при округлении.

Заключение

Рамка это не просто border. Если вы захотели анимировать рамку, у вас может возникнуть несколько проблем. Описанные здесь методы помогут сделать это, но они не идеальны. Ваш выбор зависит от требований проекта. Я составил таблицу сравнения, чтобы помочь вам с выбором.

Я рекомендую использовать box-shadow – лучшая смесь простоты, эффекта анимации, скорости и поддержки.

Автор: Stephen Shaw

Источник: //css-tricks.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: