Градиентный текст с тенью
background-clip: text;
— но это убивает возможность использовать text-shadow
. На помощь приходит SVG.Во время нашей ежегодной акции мы (Frontend Masters) использовали такое брендирование для таймера обратного отсчёта:
Надпись Ends in X days!
должна быть HTML текстом, поскольку она динамически изменяется в зависимости от даты окончания распродажи. Обратите внимание, что он окрашен градиентом, имеет обводку и отбрасывает тень.
Можно создать текстовый градиент, обрезав фон по тексту с помощью background-clip: text
, как показано ниже:
.Countdown {
background: linear-gradient(#fff000, #ff3600);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
Это создаёт градиентный фон, а затем обрезает фон по тексту. Далее мы скрываем сам текст с помощью color: transparent
. Вот пример:
Теперь необходимо добавить тень за ним… звучит просто, верно? Конечно, нет.
Очевидный способ, использование text-shadow
, выглядит плохо, потому что color: transparent
делает сам текст прозрачным, и отрисовываемая им тень оказывается выше фона.
Так что это исключено.
Решение с псевдоэлементом: Градиентный текст с тенью
Можно использовать псевдоэлемент, повторяющий текст и располагающийся за фоном основного текста, а затем безопасно использовать для него text-shadow
:
.Countdown::before {
content: attr(data-text);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
color: #000;
text-shadow: -4px 4px 1px #000, 3px 2px 1px #000, -1px -2px 1px #000, 2px 6px 3px #000;
}
Обратите внимание на множественные тени в разных направлениях, имитирующие обводку текста.
Это не идеальный вариант, поскольку для вставки в псевдоэлемент текст необходимо также добавить в data
атрибут:
<p class="Countdown CountdownFont"
data-text="Ends in 7 days">
Ends in 7 days
</p>
Это повторение, усложнение и возможность ошибок. Это также означает, что если необходимо изменить содержимое текста с помощью JavaScript, то придётся обновлять и data
атрибут. Не говоря уже, что с отрицательным z-index
могут возникнуть проблемы, когда задействованы фоны других элементов.
SVG решение: Градиентный текст с тенью
Хотя это самый сложный из методов, к SVG можно без проблем применить оба эффекта!
В коде используется SVG элемент linearGradient
для рисования текста и серия фильтров feDropShadow
для текстового элемента tspan
:
<svg width="auto" height="auto">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#fff000" />
<stop offset="100%" stop-color="#ff3600" />
</linearGradient>
</defs>
<filter id="shadow">
<feDropShadow dx="-4" dy="4" stdDeviation="1" flood-color="black" flood-opacity="0.5"/>
<feDropShadow dx="3" dy="2" stdDeviation="2" flood-color="black" flood-opacity="0.5"/>
<feDropShadow dx="-1" dy="-2" stdDeviation="1" flood-color="black" flood-opacity="0.5"/>
<feDropShadow dx="2" dy="6" stdDeviation="3" flood-color="black" flood-opacity="0.5"/>
</filter>
<text x="10" y="50" font-family="Rubik Mono One" font-size="40" fill="url(#gradient)">
<tspan filter="url(#shadow)">Ends in 7 Days</tspan>
</text>
</svg>
Приятным моментом является то, что изменить текст можно только в одном месте, а сам текст остаётся доступным для выделения, как и любой другой веб-текст. Обратите внимание, что перенос SVG <text>
не очень хорошо поддерживается и, вероятно, его лучше избегать.
Другие примеры
Я считаю этот пример градиентного текста и тени текста хорошей иллюстрацией эффектов:
Наконец, Ana Tudor предлагает несколько безумных CodePen, смешивающих тонны SVG-фильтров вместе для создания невероятных текстовых эффектов:
Развлекайтесь!