Давайте создадим эффект на чистом Css, который будет менять цвет текстовой ссылки при наведении ... но будем заполнять ссылку цветом слева направо, а не как обычно просто изменять цвет.

Мы можем сделать это четырьмя различными способами. Давайте разберем их, но не будем забывать о таких важных вещах как доступность, производительность и поддержка браузерами.
Приступим!
#Вариант 1: Использование background-clip: text
На момент написания статьи свойство background-clip: text является экспериментальной функцией и не поддерживается в Internet Explorer 11 и ниже.
В этом подходе используется сочетание вырезанного текста и градиента с резкими границами перехода цвета. Разметка состоит из одного единственного элемента - HTML-ссылки:
<a href="#">Link Hover</a>
Добавляем стили к нашей ссылке. Использование overflow: hidden обрезает любой контент вне гиперссылки во время анимации происходящей при наведении:
a {
position: relative;
display: inline-block;
font-size: 2em;
font-weight: 800;
color: royalblue;
overflow: hidden;
}
Нам нужно будет использовать линейный градиент с резким переходом на пятидесяти процентах от начального цвета ссылки к цвету которым ссылка закрасится при наведении на неё:
a {
/* Same as before */
background: linear-gradient(to right, midnightblue, midnightblue 50%, royalblue 50%);
}
Используем background-clip чтобы обрезать градиент и текст который мы будем отображать. Также, мы будем использовать свойства background-size и background-position для отображения первоначального цвета:
a {
/* Same as before */
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 200% 100%;
background-position: 100%;
}
Наконец, давайте добавим CSS свойство transition и псевдокласс ::hover к ссылке. Чтобы ссылка заполнялась слева направо при наведении, используйте свойство background-position:
a {
/* Same as before */
transition: background-position 275ms ease;
}
a:hover {
background-position: 0 100%;
}
Несмотря на то, что этот метод обеспечивает необходимый эффект при наведении, Safari и Chrome будут обрезать текстовые декорации и тени, то есть они не будут отображаться. Применение стилей текста, таких как подчеркивание, не будет работать со свойством text-decor. Возможно, следует рассмотреть другие подходы для создания подчеркиваний.
#Вариант 2: Использование ширины/высоты
Этот вариант работает с использованием дата-атрибута, который содержит тот же текст, что и в теге a.
А также изменения ширины (заполнение текста слева направо или справа налево) или высоты (заполнение текста сверху вниз или снизу вверх) псевдоэлемента, от 0% до 100% при наведении.
Вот разметка:
<a href="#" data-content="Link Hover">Link Hover</a>
Стили похожи на те, которые мы применяли в предыдущем варианте, но без свойств для фона. В этом варианте свойство text-decoration будет работать:
a {
position: relative;
display: inline-block;
font-size: 2em;
color: royalblue;
font-weight: 800;
text-decoration: underline;
overflow: hidden;
}
Мы используем небольшой трюк для копирования текста в дата-атрибуте и отображения его с помощью функции attr() в свойстве content, которое применяется к псевдоэлементу ::before. Расположим наш псевдоэлемент над текстом в ссылке.
a::before {
position: absolute;
content: attr(data-content);
/* Prints the value of the attribute */
top: 0;
left: 0;
color: midnightblue;
text-decoration: underline;
overflow: hidden;
transition: width 275ms ease;
}
Чтобы текст не переносился на следующую строку, применим свойство white-space: nowrap. Чтобы изменить цвет ссылки при наведении, задайте для псевдоэлемента ::before необходимый цвет и значение width равное 0:
a::before {
/* Same as before */
width: 0;
white-space: nowrap;
}
При наведении увеличьте ширину для ::before до 100%:
a:hover::before {
width: 100%;
}
Несмотря на то, что этот подход работает, использование свойств width или height не лучший способ для анимации. Лучше всего использовать свойства transform или opacity чтобы добиться плавного перехода со скоростью 60 кадров в секунду.
Если при этом использовать свойство text-decoration с различными значениями, то можно создать различные варианты подчеркивания при наведении. Я сделал демо, на котором показал различные варианты подчеркивания, используя CSS-свойство clip-path.
#Вариант 3: Использование clip-path
Как вы уже наверное догадались, в этом варианте, мы будем использовать CSS-свойство clip-path с многоугольной формой. У многоугольника будет четыре вершины, две из которых будут расширяться вправо при наведении:

Разметка такая же, как и в предыдущем методе. Мы снова будем использовать псевдоэлемент ::before, но CSS будет другим:
a::before {
position: absolute;
content: attr(data-content);
color: midnightblue;
text-decoration: underline;
clip-path: polygon(0 0, 0 0, 0% 100%, 0 100%);
transition: clip-path 275ms ease;
}
В отличие от предыдущих методов, text-decoration: underline должно быть назначено для псевдоэлемента ::before, чтобы цвет заполнял подчеркивание при наведении курсора.
Теперь давайте рассмотрим CSS для свойства clip-path:
clip-path: polygon(0 0, 0 0, 0% 100%, 0 100%);
Вершины многоугольника заданного при помощи clip-path установлены в процентах, и определяют координаты в следующем порядке:
- 0 0 = верхний левый
- 0 0 = вверху справа
- 100% 0 = справа внизу
- 0 100% = внизу слева
Направление эффекта заполнения можно изменить, изменив координаты.
Теперь, когда мы знаем, как задаются координаты, мы можем заставить многоугольник расширяться вправо при наведении:
a:hover::before {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
Этот вариант стилизации работает довольно хорошо, но обратите внимание, что поддержка свойства clip-path в некоторых браузерах далека от совершенства.
#Вариант 4: Использование трансформации
В этот раз, разметка будет отличаться от предыдущих вариантов. Мы будем использовать внутри нашей ссылки элемент span. Поскольку мы будем использовать дублированный контент в отдельном элементе, мы будем использовать aria-hidden="true" для улучшения доступности - это скроет его от скринридеров, чтобы контент не читался дважды:
<a href="#">
<span data-content="Link Hover" aria-hidden="true"></span>
Link Hover
</a>
CSS для элемента span содержит трансформацию, которая будет начинаться слева:
span {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
transform: translateX(-100%);
transition: transform 275ms ease;
}
Далее нам нужно заставить span скользить вправо так:

Для этого мы будем использовать CSS-функцию translateX() для которой установим значение 0:
a:hover span {
transform: translateX(0);
}
Затем мы будем использовать псевдоэлемент ::before для span, снова используя атрибут data-content, как мы делали это раньше. И установим позицию, переместив ее на 100% вдоль оси X.
span::before {
display: inline-block;
content: attr(data-content);
color: midnightblue;
transform: translateX(100%);
transition: transform 275ms ease;
text-decoration: underline;
}
Как и для элемента span, положение ::before также будет установлено в translateX(0):
a:hover span::before {
transform: translateX(0);
}
Несмотря на то, что этот метод является наиболее кроссбраузерным, для его реализации требуется больше разметки и CSS, что не очень хорошо. Тем не менее, использование CSS-свойства transform очень полезно для производительности, поскольку не вызывает перерисовок и, следовательно, обеспечивает плавные переходы CSS со скоростью 60 кадров в секунду.
#Мы сделали это!
Только что, мы рассмотрели четыре различных метода для достижения одинакового эффекта при наведении. Хотя у каждого есть свои плюсы и минусы, как вы видите, вполне реально плавно изменить цвет текста с эффектом постепенного закрашивания. Этот аккуратный и небольшой эффект сделает ваши ссылки более интерактивными.