Создаем оригинальные hover-эффекты при помощи CSS3

Мощь CSS3 огромна и в этом уроке вы сможете увидеть, как использовать его креативно. Мы собираемся создать несколько эффектов при наведении курсора мыши с помощью CSS3 transitions. При наведении курсора на эскиз будет показываться описание миниатюр, с использованием различных стилей в каждом примере.
Пожалуйста, обратите внимание, что эти примеры будут корректно работать только в современных браузерах, которые поддерживают свойства CSS3.
HTML-разметка
Структура разметки очень простая и интуитивно понятная. Создайте контейнер, который будет содержать изображение и любую другую информацию, такую как заголовок, описание и прочее.
Внутри блока с классом view вставим элемент с классом mask, который будет отвечать за наши эффекты CSS3, внутри него мы и поместим название, описание и ссылку на полное изображение. (Для некоторых примеров, нам нужно будет добавить mask как отдельный элемент и обернуть описание в div с классом content.)
После создания разметки мы создадим наши стили.
Мы установим общие правила для наших стилей, а затем мы будем добавлять специальные классы с желаемыми эффектами. В статье мы будем опускать CSS-префиксы для различных браузеров, но вы их можете увидеть в исходниках.
А теперь мы рассмотрим десять эффектов.
Пример 1

Добавим специальный класс view-first в элемент с классом view для этого эффекта. Мы будем добавлять специальный класс для каждого экземпляра view элемента (view-first, view-second, view-third, и т.д.).
В первом примере мы будем использовать только некоторые базовые переходы, чтобы создать неплохой эффект при наведении курсора:
А теперь самое интересное в нашем эффекте. Когда мы перемещаем курсор над изображением, можно использовать свойство delay чтобы имитировать простую анимацию. transition-delay, который мы используем при наведении может быть изменен, чтобы отличаться от обычного класса. В этом примере мы не использовали какой-либо задержки в обычном классе, но мы добавили delay в hover, который будет немного задерживать эффект перехода.
Пример 2

Во втором примере мы добавим специальный класс view-second, но мы оставим элемент с классом mask пустым и обернем описание в div с классом content.
Здесь класс mask будет иметь различные атрибуты, в частности мы собираемся применить свойство transform (translate и rotate). Описание элементов будут перемещены так, чтобы мы могли сдвинуть их вместе при наведении:
Для нашего hover-эффекта мы используем translate-преобразование для того, чтобы перемещать наши элементы на место. mask также будет поворачиваться. Элементы описания будут двигаться с небольшой задержкой:
Пример 3

В третьем примере мы будем использовать translate и rotate преобразование:
Это простые инструкции, которые будут применяться при наведении. Теперь мы будем переворачивать описание элементов, установив transition-delay соответственно:
Пример 4

В четвертом примере мы выполним простое уменьшение изображения и увеличение нашего контента с вращением, все это благодаря scale преобразованию. Мы установим transition-delay равным 0,2 для стилей изображения, но при наведении мы изменим его на 0s. Это позволит начать анимацию немедленно при наведении мыши, но задержать её когда курсор уходит.
Это инструкции, чтобы получить этот эффект — с CSS3 можно делать все :).
Пример 5

В этом пятом примере мы будем использовать свойство translate наряду с transition-timing-function ease-in-out для того, чтобы сдвинуть контент с левой стороны.
Эффект при наведении будет сдвигать изображение вправо и описание появится с левой стороны, как если бы оно сдвинуло картинку:
Пример 6

В этом примере мы сделаем описание появляющееся спереди, уменьшим изображение до исходного размера (scale c 10 до 1). Кнопка «read more» будет появляться снизу (translate).
Обратный переход будет задержан таким образом, чтобы он выглядел гладким:
Пример 7

В седьмом примере идея в том, чтобы повернуть изображение в центре и переместить его вдаль. Затем появится описание, пряча за собой вращающиеся изображение.
При наведении мы добавим задержку для элементов с описанием. Это позволит нам видеть вращающиеся изображение, прежде чем описание скроет картинку. В обратном переходе все исчезнет сразу же, и мы увидим изображение вращающееся в обратном направлении:
Пример 8

В восьмом примере мы будем использовать анимацию и воссоздадим эффект отскока. Описание будет спускаться снизу и отскакивать от нижней границы.
Мы добавим анимацию для элемента mask и определим некоторые установки задержки для элементов описания:
Чтобы воссоздать настоящий эффект отскока мы воспользуемся translateY, как вы можете видеть там несколько кадров, которые создают этот эффект:
Пример 9

В этом примере мы будем использовать два элемента mask, чтобы сдвигать их с правого нижнего и с левого верхнего углов:
Элементы mask будут иметь различные значения translation и transfrom-origin. А также мы укажем что один выровнен по верхней границе, а другой по нижней:
При наведении, мы сделаем так, что содержание будет появляться как бы из под двух, съезжающих в центр, элементов mask:
Мы настроили transition-delay для элементов mask таким образом, что, когда мы наводим курсор, переход происходит мгновенно, но при уходе мыши, задержка будет больше.
Пример 10

В последнем примере, мы будем увеличивать изображение, а затем прятать, перенося описание на передний план. Мы можем сделать это, используя шкалу преобразования (scale transform) и настраивая уровень прозрачности:
При наведении мы просто масштабируем изображение, а зачем прячем его, уменьшив его прозрачность до 0:
Заключение
CSS3 имеет действительно большой потенциал для создания красивых эффектов. Вскоре, надеюсь, мы будет в состоянии избегать использование JavaScript для создания простых эффектов и полагаться на 100% на CSS, во всех браузерах.
Я надеюсь, что вам понравились эти эксперименты, но прежде всего я надеюсь, что они смогут вдохновить вас на создание своих эффектов.
How to Make a Nice Hover Effect With CSS
Transition animation in CSS (Cascading Style Sheets) to fuel your HTML components
![]()
This is where the fun begins when playing with some CSS properties. In any website front-end web development project that you have, you always have the parts that you want to have nice any good looking animation and transition effects.
CSS Transition has always been fun to use in making of web pages look cool and attractive. Any components in your website such as buttons, links, or cards can have animation effects.
There are several CSS transition property that can make your website looks cool. Transition can take almost other CSS properties that you want to animate such as opacity, background color, transform, and other properties. See this great explanatory post from Sara Cope about Transition Properties.
I will take you on two things I want to introduce into animating transitions. Buttons and Cards are popular HTML components that are widely used on websites.
1. Buttons
We can start with writing the HTML buttons to the canvas. You can use your own CSS style for the projects or use a CSS framework that you like. I use the Bootstrap 4 framework for this case.
Как сделать чудесные, анимированные всплывающие подсказки с помощью CSS.
Всплывающие подсказки — это отличный способ улучшить пользовательский интерфейс — UI, когда вашим пользователям нужно дополнительное описание для той причудливой иконки, или когда они хотят перестраховаться перед тем, как нажать на кнопку, ну или может быть заголовок для «пасхального яйца» который идёт вместе с изображением. Так давайте сделаем анимированные всплывающие подсказки прямо сейчас, используя не что иное как HTML и CSS.
Образец
Вот над чем мы собираемся работать:
Прежде чем прыгать в котёл, давайте взглянем на то, что мы собираемся сварганить. Наша цель — добавить всплывающую подсказку простым способом, поэтому мы сделаем это добавив атрибут tooltip :
Замечание о доступности и возможностях
Если вы ищете всплывающие подсказки совместимые с 508-м разделом (стандарт, принятый в США, для создания веб-ресурсов для людей с ограниченными возможностями) или вам нужны более умные подсказки с обнаружением столкновения контейнеров и/или поддержкой HTML содержимого или обычного текста, существует множество решений, в которых для этих задач используются сторонние скрипты.
В этом руководстве потребности в доступности особо не рассматриваются. Вы знаете своих пользователей и то, что им нужно, поэтому убедитесь что вы учили и уважаете их нужды.
Давайте определим чего следует ожидать
- JavaScript не требуется
- Мы будем использовать селектор атрибута (не название класса), используя встроенные возможности CSS.
- Будем использовать существующие DOM элементы (никакие новые элементы не потребуются в вашей разметке*)
- В примерах кодов не используются префиксы (поэтому если вам нужно, сами добавьте префикс для вашего браузера)
- Для переключения всплывающих подсказок будем использовать событие в наведении мыши — mouseover/hover
- Всплывающие подсказки поддерживают только простой текст (HTML, изображения и прочее не поддерживается)
- Лёгкая анимация при вызове всплывающих подсказок
Отлично! Давайте раскачаем эту лодку!
Ой, подождите! Есть сноска (*), давайте сначала договоримся об “дополнительная разметка не нужна”. Всё-таки это магия! Нашим всплывающим подсказкам действительно не нужны дополнительные DOM элементы, так как они сделаны полностью на псевдо-элементах ( ::before и ::after ), которыми мы можем управлять с помощью CSS.
Если вы уже используете псевдоэлементы из другого набора стилей и хотите создать всплывающую подсказку для этого элемента, вам может потребоваться немного изменить структуру.
Никакой вечеринки без всплывающих подсказок!
Подождите. Господа! Ещё одна оговорка: CSS-позиционирование. Чтобы всплывающие подсказки функционировали должным образом, их родительский элемент (то, к чему мы прикрепляем подсказку) должен быть
- position: relative , или
- position: absolute , или
- position: fixed
По существу, что-либо кроме position: static — это режим позиционирования по умолчанию, назначенный практически на все элементы вашим браузером. Всплывающие подсказки имеют абсолютное позиционирование и таким образом им нужно знать границы, в которых их абсолютность имеет место быть. Указанное по умолчанию статическое позиционирование не имеет свои собственные границы и не даст вашим всплывающим подсказкам что-то, от чего можно оттолкнуться, поэтому подсказки будут использовать ближайший родительский элемент, у которого четко объявлена граница.
Вам нужно определить, какое позиционирование работает лучше, когда вы используйте подсказки. По этому руководству подразумевается, что родительский элемент настроен на position: relative . Если ваш интерфейс основывается на абсолютном позиционировании элементов, тогда могут потребоваться некоторые изменения (дополнительная разметка), чтобы навесить подсказку на этот элемент.
Ну что ж, запрыгиваем и понеслась!
Селектор атрибута: Быстрое напоминание
Большинство CSS правил написаны для использования по названию класса, например .this-thing , но в CSS есть несколько типов селекторов. Для наших чудесных подсказок мы будем использовать селектор атрибута/свойства — объявляется квадратными скобками.
Когда браузер встречает что-то вроде этого:
он поймет, что нужно применить правила [foo] , потому что в теге <span> имеется атрибут названный foo. В этом случае, сам span будет полупрозрачного черного цвета с белым текстом.
HTML элементы имеют различные встроенные атрибуты, а также мы можем придумать свои собственные. Наподобие foo , или tooltip . По умолчанию, HTML не знает что он означает, но с помощью CSS мы можем подсказать HTML, что с этим делать.
Почему селекторы атрибутов?
Мы будем использовать селекторы атрибутов в первую очередь для разделения задач. Использование атрибутов вместо имён классов не дает нам никаких бонусных очков в этой битве; классы и атрибуты имеют одинаковое предназначение. Однако, используя атрибуты, мы можем держать наш контент в содержимом, поскольку атрибуты HTML могут иметь значения, в то время как имена классов не могут.
Рассмотрим в этом примере кода: имя класса .tooltip и атрибут [tooltip] . Имя класса является одним из значений атрибута [class] , в то время, как атрибут tooltip имеет значение, а содержащее текст, который мы хотим отобразить.
Теперь добавляем Алхимию в подсказку
Наши подсказки будут использовать два атрибута:
- tooltip : содержит содержимое подсказки (строка простого текста)
- flow :не обязательно; позволяет нам управлять с тем, как раскрыть подсказку. Мы можем использовать много способов размещения, но мы рассмотрим 4 обычных направления:
сверху, слева, справа, снизу.
Теперь давайте настроим основу для всех подсказок. Правила 1-5 пунктов применяются для всех подсказок, независимо от того какое направление flow мы им зададим. Пункты 6–7 имеют различия для значений flow .
1. Относительность
Это для родительского элемента подсказки. Давайте назначим позицию так, чтобы абсолютное расположение частей подсказки (псевдоэлементы ::before и ::after ) находилось в контексте родительского элемента, а не в контексте страницы в целом или прародительского элемента, или какого-то другого внешнего элемента в дереве DOM.
2. Настало время для псевдо-элементов
Пришло время для выхода псевдоэлементов на сцену. Пока что, мы зададим общее свойство для обоих частей ::before и ::after . Свойство content — выполняет основную работу псевдо-элемента, и скоро мы до него доберемся.
3. Dink
Я не знаю, какое отношение имеет к этому «dink, но я всегда называл это так. Эта маленькая, треугольная, заострённая часть, придающая подсказкам вид, как у пузыря с диалогом, указывающая туда, откуда оно появилось. Заметьте, что мы используем прозрачный цвет ( transparent ) для границы; мы добавим цвет позже, также как и зависимость подсказки от направления flow .
Это не опечатка, что значение свойства имеет пустую строку — content: «»; . Нам там ничего не нужно, но нам нужно это свойство для работы псевдо-элемента.
Чтобы создать треугольник, мы задаем сплошную границу с некоторой толщиной для пустого прямоугольника (без содержимого), без ширины и высоты, и цвет будет только у одной стороны границы. Для получения дополнительной информации ознакомьтесь со следующим руководством:
4. Пузырики!
Мы добрались до сути. Заметьте что content: attr(tooltip) говорит, “Этот псевдо-элемент должен использовать значение атрибута tooltip в качестве контента.” Вот почему использование атрибутов вместо названия классов является отличным решением!
Заметьте, что значения z-index присутствуют для обоих элементов и «dink», и пузырика. Это произвольные значения, но имейте в виду, что значения z-index являятся относительными. Разъяснение: значение z-index: 1001 внутри элемента с z-index: 3, означает, что элемент 1001 будет самым верхним элементом внутри этого контейнера с z-index: 3.
Свойство пузырика z-index должно быть как минимум на 1 меньше чем z-index у «dink». Если это значение такое же или выше чем у «dink», вы можете столкнуться с эффектом неравномерной цветовой окраски «dink», если вы применяете box-shadow для ваших подсказок.
Чтобы узнать подробнее о свойстве z-index, взгляните на следующее руководство:
5. Взаимодействие с действием
Наши подсказки активируются при наведении мыши на элемент с подсказкой… Почти.
Если вы вернётесь нашему блоку со стилями на Шаге 2, вы должны увидеть, что мы использовали opacity: 0; наряду с display: none; для частей нашей подсказки. Мы сделали так, чтобы использовать эффекты анимации CSS, при отображении и скрытии подсказки.
Свойство display не может быть анимировано, а свойство opacity может! И напоследок мы займёмся анимацией. Если вас не интересуют анимированные подсказки, просто уберите opacity: 0; на Пункте 2 и не обращайте внимания на анимацию в Пункте 7.
Последнее, что нам нужно, все еще относится ко всем подсказкам — это способ подавить всплывающую подсказку, если у нее нет содержимого. Если вы заполняете всплывающие подсказки некоторой динамической системой (Vue.js, Angular, или React, PHP и т.д.), нам не нужны тупые пустые пузырьки!
6. Управление направлением
Этот шаг может быть довольно сложным, поскольку мы будем использовать некоторые не столь распространенные селекторы, чтобы помочь нашим подсказкам определиться с их местами размещения на основе их flow значений (или их отсутствия).
Прежде чем перейти к стилям, давайте посмотрим на некоторые шаблоны селекторов, которые мы будем использовать.
Это говорит браузеру: «Для всех элементов с атрибутом tooltip , которые либо не имеют атрибута flow , либо имеют flow со значением, которое начинается с “наверх”: применить эти стили к своему псевдониму ::before .»
Мы используем шаблон, так что они могут быть распространены на другие flow без необходимости повторять CSS. Этот шаблон flow^=»up» использует сопоставитель ^= (начинается с). Это позволяет стилям также применяться к up-right и up-left (вправо-вверх и влево-верх), вы можете захотеть использовать такие направления. Мы не будем описывать их здесь, но вы можете увидеть, как они используются в моей оригинальной демонстрации всплывающей подсказки в CodePen .
Ниже перечислены блоки CSS для всех четырех направлений, рассматриваемых в этом уроке.
Наверх (по умолчанию):
Влево:
Вправо:
7. Анимируем всё
Анимация просто потрясающая штука. Анимация может:
- помочь пользователям чувствовать себя комфортно
- помочь пользователям с пространственной ориентацией в вашем интерфейсе
- привлечь внимание к вещам, которые необходимо увидеть
- смягчить элементы интерфейса, которые в противном случае имели бы только резкий эффект вкл/выкл
Наши подсказки будут подпадать под это последнее описание. Вместо того, чтобы всплывать и мгновенно выскакивать, давайте сделаем нашим текстовым пузырям более легкий эффект.
@keyframes
Нам понадобятся два вида анимации @keyframe . Подсказки вверх/вниз будут использовать keyframe tooltips-vert , а подсказки влево/вправо будут использовать keyframe tooltips-horz . Обратите внимание, что в обоих этих keyframe мы определяем только желаемое конечное состояние всплывающих подсказок. Нам не нужно знать, откуда они появляются (в подсказках есть информация о стиле). Мы просто хотим управлять тем, куда они направляются.
Теперь нам нужно применить эти keyframe к подсказкам, когда пользователь наводит курсор мыши на элементы с атрибутами [tooltip] . Поскольку мы используем различные направления для управления отображением всплывающих подсказок, нам необходимо определить эти возможности в стилях.
Используйте :hover, чтобы передать управление анимации
Помните, что мы не можем анимировать свойство display , но мы можем дать всплывающим подсказкам эффект затухания, манипулируя opacity . Мы также анимируем свойство transform, которое придает подсказкам еле-заметное движение, как будто они вылетают, указывая на их теггированне элементы.
Обратите внимание на ключевое слово forwards в объявлении анимации. Это говорит анимации не сбрасываться после одного выполнения, а двигаться вперед и оставаться до конца.
Вывод
Фантастическая работа! Мы многое рассказали на этом уроке, и теперь у нас есть аккуратная коллекция всплывающих подсказок, показывающих нашу напряженную работу:
Мы лишь нацарапали поверхность того, что можно делать с помощью всплывающих подсказок CSS. Повеселитесь, поиграйте с ними, продолжайте экспериментировать и придумывайте свои собственные рецепты!
An Interactive Guide to CSS Transitions
The world of web animations has become a sprawling jungle of tools and technologies. Libraries like GSAP and Framer Motion and React Spring have sprung up to help us add motion to the DOM.
The most fundamental and critical piece, though, is the humble CSS transition. It's the first animation tool that most front-end devs learn, and it's a workhorse. Even the most grizzled, weathered animation veterans still reach for this tool often.
There's a surprising amount of depth to this topic. In this tutorial, we'll dig in and learn a bit more about CSS transitions, and how we can use them to create lush, polished animations.
This tutorial is meant to be accessible to developers of all experience levels. It can be thought of as "CSS transitions 101". That said, I've sprinkled in some interesting and obscure tidbits — no matter your experience level, I bet you'll learn something!
The main ingredient we need to create an animation is some CSS that changes.
Here's an example of a button that moves on hover, without animating:
Code Playground
This snippet uses the :hover pseudoclass to specify an additional CSS declaration when the user's mouse rests atop our button, similar to an onMouseEnter event in JavaScript.
To shift the element up, we use transform: translateY(-10px) . While we could have used margin-top for this, transform: translate is a better tool for the job. We'll see why later.
By default, changes in CSS happen instantaneously. In the blink of an eye, our button has teleported to a new position! This is incongruous with the natural world, where things happen gradually.
We can instruct the browser to interpolate from one state to another with the aptly-named transition property:
Code Playground
transition can take a number of values, but only two are required:
If you plan on animating multiple properties, you can pass it a comma-separated list:
transition-property takes a special value: all . When all is specified, any CSS property that changes will be transitioned.
It can be tempting to use this value, as it saves us a good chunk of typing if we're animating multiple properties, but I recommend not using it.
As your product evolves, you (or someone on your team) will likely wind up updating this code at some point in the future. An unexpected animation could slip through.
Animation is like salt: too much of it spoils the dish. It pays to be really precise with the properties we animate.
When we tell an element to transition from one position to another, the browser needs to work out what each "intermediary" frame should look like.
For example: let's say that we're moving an element from left to right, over a 1-second duration. A smooth animation should run at 60fps * , which means we'll need to come up with 60 individual positions between the start and end.
Let's start by having them be evenly-spaced:
To clarify what's going on here: each faded circle represents a moment in time. As the circle moves from left to right, these are the frames that were shown to the user. It's like a flipbook.
In this animation, we're using a linear timing function. This means that the element moves at a constant pace; our circle moves by the same amount each frame.
There are several timing functions available to us in CSS. We can specify which one we want to use with the transition-timing-function property:
Or, we can pass it directly to the transition shorthand property:
linear is rarely the best choice — after all, pretty much nothing in the real world moves this way * . Good animations mimic the natural world, so we should pick something more organic!
Let's run through our options.
ease-out comes charging in like a wild bull, but it runs out of energy. By the end, it's pootering along like a sleepy turtle.
Try scrubbing with the timeline; notice how drastic the movement is in the first few frames, and how subtle it becomes towards the end.
If we were to graph the displacement of the element over time, it'd look something like this:
When would you use ease-out ? It's most commonly used when something is entering from off-screen (eg. a modal appearing). It produces the effect that something came hustling in from far away, and settles in front of the user.
ease-in , unsurprisingly, is the opposite of ease-out . It starts slow and speeds up:
As we saw, ease-out is useful for things that enter into view from offscreen. ease-in , naturally, is useful for the opposite: moving something beyond the bounds of the viewport.
This combo is useful when something is entering and exiting the viewport, like a modal. We'll look at how to mix and match timing functions shortly.
Note that ease-in is pretty much exclusively useful for animations that end with the element offscreen or invisible; otherwise, the sudden stop can be jarring.
Next up, ease-in-out . It's the combination of the previous two timing functions:
This timing function is symmetrical. It has an equal amount of acceleration and deceleration.
I find this curve most useful for anything that happens in a loop (eg. an element fading in and out, over and over).
It's a big step-up over linear , but before you go slapping it on everything, let's look at one more option.
If I had a bone to pick with the CSS language authors when it comes to transitions, it's that ease is poorly named. It isn't descriptive at all; literally all timing functions are eases of one sort or another!
That nitpick aside, ease is awesome. Unlike ease-in-out , it isn't symmetrical; it features a brief ramp-up, and a lot of deceleration.
ease is the default value — if you don't specify a timing function, ease gets used. Honestly, this feels right to me. ease is a great option in most cases. If an element moves, and isn't entering or exiting the viewport, ease is usually a good choice.
An important note about all of these demos: time is constant. Timing functions describe how a value should get from 0 to 1 over a fixed time interval, not how quickly the animation should complete. Some timing functions may feel faster or slower, but in these examples, they all take exactly 1 second to complete.
If the provided built-in options don't suit your needs, you can define your own custom easing curve, using the cubic bézier timing function!
All of the values we've seen so far are really just presets for this cubic-bezier function. It takes 4 numbers, representing 2 control points.
Bézier curves are really nifty, but they're beyond the scope of this tutorial. I'll be writing more about them soon though!
In the meantime, you can start creating your own Bézier timing functions using this wonderful helper from Lea Verou:
Once you come up with an animation curve you're satisfied with, click “Copy” at the top and paste it into your CSS!
You can also pick from this extended set of timing functions. Though beware: a few of the more outlandish options won't work in CSS.
When starting out with custom Bézier curves, it can be hard to come up with a curve that feels natural. With some practice, however, this is an incredibly expressive tool.
I have a confession to make: the demonstrations above, showing the different timing functions, were exaggerated.
In truth, timing functions like ease-in are more subtle than depicted, but I wanted to emphasize the effect to make it easier to understand. The cubic-bezier timing function makes that possible!
Earlier, we mentioned that animations ought to run at 60fps. When we do the math, though, we realize that this means the browser only has 16.6 milliseconds to paint each frame. That's really not much time at all; for reference, it takes us about 100ms-300ms to blink!
If our animation is too computationally expensive, it'll appear janky and stuttery. Frames will get dropped, as the device can't keep up.
Experience this for yourself by tweaking the new "Frames per second" control:
In practice, poor performance will often take the form of variable framerates, so this isn't a perfect simulation.
Animation performance is a surprisingly deep and interesting area, well beyond the scope of this introductory tutorial. But let's cover the absolutely-critical, need-to-know bits:
If you're interested in learning more about animation performance, I gave a talk on this subject at React Rally. It goes deep into this topic:
Depending on your browser and OS, you may have noticed a curious little imperfection in some of the earlier examples:
Pay close attention to the letters. Notice how they appear to glitch slightly at the start and end of the transition, as if everything was locking into place?
This happens because of a hand-off between the computer's CPU and GPU. Let me explain.
When we animate an element using transform and opacity , the browser will sometimes try to optimize this animation. Instead of rasterizing the pixels on every frame, it transfers everything to the GPU as a texture. GPUs are very good at doing these kinds of texture-based transformations, and as a result, we get a very slick, very performant animation. This is known as “hardware acceleration”.
Here's the problem: GPUs and CPUs render things slightly differently. When the CPU hands it to the GPU, and vice versa, you get a snap of things shifting slightly.
We can fix this problem by adding the following CSS property:
will-change is a property that allows us to hint to the browser that we're going to animate the selected element, and that it should optimize for this case.
In practice, what this means is that the browser will let the GPU handle this element all the time. No more handing-off between CPU and GPU, no more telltale “snapping into place”.
will-change lets us be intentional about which elements should be hardware-accelerated. Browsers have their own inscrutable logic around this stuff, and I'd rather not leave it up to chance.
There's another benefit to hardware acceleration: we can take advantage of sub-pixel rendering.
Check out these two boxes. They shift down when you hover/focus them. One of them is hardware-accelerated, and the other one isn't.