Анимированное подчёркивание ссылок в CSS

Анимированное подчёркивание ссылок на чистом CSS: от центра, слева, справа. Без JavaScript и лишней разметки. Разбор кода, подводные камни и примеры.

Эффект анимированного подчёркивания ссылок, когда при наведении линия плавно вырастает из центра, выглядит приятно и современно. Разберём, как создать анимацию ссылок на чистом CSS.

Что вы получите:

Важно: Для эффекта не нужен JavaScript и лишние элементы в HTML. Вся магия — через псевдоэлемент ::before и CSS-трансформации.

Базовая настройка: сбрасываем стандартные настройки

Прежде чем рисовать свою линию, нужно убрать стандартную и подготовить ссылку к позиционированию.

Что делаем:

  1. Отключаем встроенное подчёркивание браузера (text-decoration: none)
  2. Фиксируем цвет ссылки — при наведении он не должен меняться, чтобы не отвлекать от анимации линии
  3. Задаём position: relative — без этого псевдоэлемент будет позиционироваться относительно всего документа, а не относительно ссылки
a {
position: relative;
color: #000;
text-decoration: none;
}

a:hover {
color: #000; /* Цвет не меняется при наведении */
}

Создаём линию: псевдоэлемент и его подводные камни

Теперь добавим невидимую линию, которая будет появляться при наведении. Для этого используем псевдоэлемент ::before.

Базовый код

a::before {
content: ""; /* Без контента псевдоэлемент не появится */
position: absolute; /* Уходим из потока, опираемся на родителя (a) */
display: block; /* Чтобы width работал */
width: 100%;
height: 2px;
bottom: 0; /* Прижимаем к нижнему краю ссылки */
left: 0;
background-color: #000;
transform: scaleX(0); /* Прячем линию, сжимая по горизонтали */
transition: transform 0.3s ease; /* Плавность */
}

Как это работает:

Важное примечание про display: block и ширину

Почему: строчные элементы игнорируют ширину. Чтобы подчёркивание точно растягивалось по тексту, добавьте ссылке display: inline-block:

a {
display: inline-block; /* Сохраняет строчное поведение, но позволяет задавать ширину */
position: relative;
color: #000;
text-decoration: none;
}

inline-block — золотая середина: ссылка не ломает вёрстку (не переносит строки), но псевдоэлемент корректно наследует её ширину.

Включаем анимацию: первый рабочий пример

Теперь сделаем линию видимой при наведении курсора. Для этого меняем масштаб с 0 на 1 у псевдоэлемента внутри состояния :hover.

Код активации

a:hover::before {
transform: scaleX(1); /* Показываем линию на всю ширину */
}

Полный рабочий пример

СSS код
a {
position: relative;
color: #000;
text-decoration: none;
display: inline-block; /* Гарантия ширины для псевдоэлемента */
}

a:hover {
color: #000;
}

a::before {
content: "";
position: absolute;
display: block;
width: 100%;
height: 2px;
bottom: 0;
left: 0;
background-color: #000;
transform: scaleX(0);
transition: transform 0.3s ease;
}

a:hover::before {
transform: scaleX(1);
}

See the Pen

Результат: при наведении линия плавно вырастает из центра к краям.

Управляем направлением анимации подчёркивания

Сейчас линия растёт из центра, потому что у transform по умолчанию стоит точка трансформации ровно посередине элемента. Чтобы изменить направление, правим свойство transform-origin.

Как это работает

Код для разных направлений

Анимация с левого края:

a::before {
/* ... все те же стили ... */
transform-origin: left;
}

Анимация с правого края:

a::before {
/* ... все те же стили ... */
transform-origin: right;
}

Важное уточнение про top

В некоторых примерах в интернете вы можете встретить запись transform-origin: top left или transform-origin: top right.

Для горизонтальной линии параметр top (вертикальная координата) не влияет на анимацию — линия все равно прижата к низу свойством bottom: 0. Но синтаксис требует указать оба значения.

Можно писать проще:

transform-origin: left;  /* Браузер поймёт и установит вертикаль по умолчанию */
transform-origin: right;

Главное — запомнить: меняя left на right, мы меняем точку старта анимации.

See the Pen

Эксперименты и вариации: что ещё можно сделать

Базовый приём освоен. Теперь несколько идей, как его развить и подстроить под свои задачи.

Меняем толщину и цвет

Простое изменение параметров height и background-color даёт другой характер анимации:

a::before {
height: 4px; /* Жирная линия */
background-color: #ff6b6b; /* Красноватый оттенок */
}

Подчёркивание сверху

Достаточно заменить bottom: 0 на top: 0 — и линия будет расти над текстом:

a::before {
bottom: auto; /* Сбрасываем */
top: 0; /* Прижимаем к верхнему краю */
}

Диагональное подчёркивание

Немного безумия — добавим поворот:

a::before {
...
bottom: 40%; /* Поднимаем линию */
...
}

a:hover::before {
transform: scaleX(1) rotate(5deg); /* Увеличиваем и слегка поворачиваемся */
}

Угол поворота текста rotate(5deg) зависит от длинны текста.

Разная скорость появления и исчезновения

Можно сделать так, чтобы линия появлялась медленно, а исчезала быстро (или наоборот):

a::before {
transition: transform 0.3s ease; /* Появление */
}

a:hover::before {
transform: scaleX(1);
transition: transform 0.1s ease; /* Исчезновение будет быстрым */
}

Линия не на всю ширину

Хотите, чтобы подчёркивание было короче текста? Вместо width: 100% задайте фиксированную ширину и центрируйте:

a::before {
width: 50%;
left: 25%; /* Сдвигаем, чтобы линия была по центру */
}

Заключение: что в итоге

Мы разобрали чистый CSS-подход к анимации подчёркивания ссылок. Без лишнего кода, без изменения HTML, без JavaScript.

Что важно запомнить:

Что дальше:

Попробуйте собрать свою версию. Начните с центра, потом поиграйте с направлением, затем добавьте нестандартный цвет. Этот приём настолько гибкий, что его можно подстроить под любой дизайн — от строгих корпоративных сайтов до креативных портфолио.

Копируйте код, меняйте параметры и находите свои уникальные сочетания.

Дополнительные материалы

Предыдущая Статья

Цвета CSS: Полное руководство по RGB, HSL, LCH, LAB и HWB моделям

Следующая Статья

CSS с селекторами атрибутов