Задайте градиент фоном элемента — как для обычного блока.
02
background-clip: text
Обрежьте фон по контуру букв. Для Safari нужен префикс -webkit-.
03
-webkit-text-fill-color: transparent
Сделайте заливку букв прозрачной — сквозь неё проступит фон.
04
@supports (…)
Оберните правило в проверку поддержки, чтобы в старых браузерах остался обычный цвет.
04
Частые ошибки
Текст исчез
Прозрачный цвет задан, а background-clip не сработал. Без @supports текст станет невидимым — всегда оставляйте фолбэк color.
Градиент на всю ширину строки
У блочного элемента фон тянется на всю ширину, и буквам достаётся лишь кусок перехода. Используйте display: inline-block.
Выделение текста не видно
При прозрачной заливке выделение может пропасть. Задайте ::selection с непрозрачным цветом.
05
Частые вопросы
Safari долго понимал только префиксную форму свойства, поэтому в правиле нужны обе строки: -webkit-background-clip: text и background-clip: text. Заливку букв делает прозрачной тоже префиксное -webkit-text-fill-color: transparent — его понимают все современные браузеры. Если забыть префикс, Safari покажет прямоугольник градиента вместо букв или прозрачный текст без фона. В коде рецепта обе формы уже стоят, а проверка в @supports учитывает и ту, и другую.
У строчного элемента фон рисуется отдельно для каждой строки, и по умолчанию градиент растягивается на всю фразу, а затем режется на куски. Чтобы каждая строка получила переход целиком, добавьте box-decoration-break: clone с префиксом -webkit-. Для заголовка в несколько строк проще оставить display: inline-block: тогда градиент ложится на весь блок сразу, а переход идёт по ширине самой длинной строки.
Обычный text-shadow здесь не годится: заливка букв прозрачна, и тень просвечивает сквозь них, перекрашивая градиент. Используйте filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .25)) на самом элементе — фильтр строит тень по уже нарисованным буквам и не лезет внутрь. Второй вариант — продублировать текст псевдоэлементом с тенью под основным слоем, но это лишняя разметка ради того же результата.
Да: это обычный текст, а не картинка, поэтому его выделяют, копируют, находят поиском по странице и читают скринридеры. Проблема одна — при прозрачной заливке выделение бывает почти незаметным, потому что подсветка ложится под прозрачные буквы. Задайте ::selection с непрозрачным цветом текста и фона, и выделенный фрагмент станет читаемым. Индексация поисковиками от приёма тоже не страдает.
Сделайте фон шире текста через background-size: 200% 100% и двигайте background-position в @keyframes — буквы останутся на месте, а перелив поедет внутри них. Сам градиент между значениями браузер не анимирует, позицию фона — анимирует. Не забудьте блок @media (prefers-reduced-motion: reduce) с animation: none. Готовый каркас анимации — на странице рецепта «Анимированный градиент», его можно соединить с этим рецептом.
Скринридер читает его как обычный текст, а вот глазам может достаться разный контраст в разных буквах. Проверяйте не один цвет, а весь переход против фона страницы: светлый край градиента на белом фоне легко падает ниже 4,5:1. Для заголовков крупнее 24 пикселей достаточно 3:1. Хорошее правило — оба края градиента должны проходить порог по отдельности, тогда пройдёт и середина.