Gradient Text with a Drop Shadow

During our annual promotion, we had this branding for the countdown timer:

The “Ends in X days!” needed to be HTML text since it’s dynamic based on the sale end date. Note that it both colored with a gradient and has both a stroke and a drop shadow.

We can achieve a text gradient by clipping the background to the text with background-clip: text, like this:

.Countdown {
  background: linear-gradient(#fff000, #ff3600);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}Code language: CSS (css)

This creates a gradient background and then clips the background to the text. Then we hide the actual text itself with color: transparent. Here’s the demo:

Now I want to add a shadow behind it… sounds simple, right? Of course not.

The obvious way, using text-shadow, looks bad because color: transparent makes the text itself transparent, and the shadow it renders is actually above the background we’re setting.

So that’s out.

Pseudo Element Solution: Gradient Text with a Drop Shadow

We can use a pseudo element that replicates the text and layers itself behind the background of the main text, and we can then use text-shadow on that safely:

.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;
}Code language: CSS (css)

Note the multiple shadows are in multiple directions simulating stroked text.

It’s not ideal since we also have to add the text to the data attribute in order to be inserted into the pseudo element:

<p class="Countdown CountdownFont" 
  data-text="Ends in 7 days">
  Ends in 7 days
</p>Code language: HTML, XML (xml)

That is repetitive, heavier, and error-prone. It also means that if you need to change the text contents via JavaScript, you’ll also need to keep the data attribute updated as well. Not to mention negative z-index can have trouble when there is other elements backgrounds involved.

SVG Solution: Gradient Text with a Drop Shadow

Although it’s the most complex of the methods, you can apply both effects to an SVG, no problem!

In the code we use the linearGradient SVG element to draw the text, and a series of feDropShadow filters to the text span element:

<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>Code language: HTML, XML (xml)

The nice thing here is there’s only one place to change the text, and the text remains selectable and accessible like any other web text. Do note that wrapping SVG <text> isn’t particularly well supported and probably best to avoid.

Other Examples in the Wild

I did find this quick shot of gradient text and text shadow a nice reference of types of effects:

Finally, Ana Tudor has some wild CodePens blending tons of SVG Filters together to make wild text effects:

Have fun!

Wanna learn SVG & Animation deeply?

Leave a Reply

Your email address will not be published. Required fields are marked *

Did you know?

Frontend Masters Donates to open source projects. $313,806 contributed to date.