25

I am trying to achieve a gradient + text shadow effect in Chrome/Safari using CSS text-shadow and a combination of text-shadow and background-image: -webkit-gradient, see example blw. I can only make one of the effects apply(if I add the shadow the gradient disappears. What am I doing wrong?

h1 {
font-size: 100px;
background-image: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 1px 1px #fff;
}
mac
  • 9,885
  • 4
  • 36
  • 51

4 Answers4

20

The gradient "disappears" because the text-shadow is on a level above the background.

  1. The text (which is transparent)
  2. The shadow
  3. The background.

We can work around this by copying the text and put it below the original layer, then apply the shadow there, for example:

  h1 {
    position: relative;
    font-size: 100px;
    text-align: center;
  }
  
  h1 div {
    background-image: linear-gradient(white, black);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    position: absolute; 
    width: 100%;
}
  h1:after {
    text-shadow: 10px 10px 11px #fff;
    color: transparent;
  }
  
  #hello:after {
        content: 'Hello World';
  }
  <h1 id="hello"><div>Hello World</div></h1>
Tamás Bolvári
  • 2,976
  • 6
  • 34
  • 57
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • Thanks. How would I apply text-align to this? I cannot get the gradient to follow along? – mac Sep 27 '10 at 11:49
13

With no extra HTML markup or pseudo elements you can achieve this effect using the filter property and drop-shadow function. This method also works with a background image vs gradient.

h1 {
  font:54px 'Open Sans', 'Helvetica', Arial, sans-serif;
  background-image: linear-gradient(#787878, #484848);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  -webkit-filter: drop-shadow(2px 2px #333);
          filter: drop-shadow(2px 2px #333);
}

Fiddle: https://jsfiddle.net/eywda89g/

Tamás Bolvári
  • 2,976
  • 6
  • 34
  • 57
Ken
  • 368
  • 3
  • 11
  • 1
    This is nice. But: If the text has several lines, the gradient goes across all lines, not per line. Is there a way to make the gradient for text per line? – Ralf Oct 30 '21 at 20:45
  • I believe this is a better alternative to the accepted answer! – Shahriar Feb 19 '22 at 09:48
5

This answer is similar to the answer by @KennyTM above, except his answer has the shadow hard-coded into the CSS, which is not suitable for dynamic text such as in a CMS. Also, his method requires a separate ID for each instance, which would be very tedious if you plan to use this effect a lot. The example below uses a class instead, and allows dynamic text.

Try this:

h1 {
    position: relative;
    font-size: 100px;
    text-align: center;
}

h1 div {
    background-image: linear-gradient(teal, black);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    position: absolute; 
    width: 100%;
}
h1:after {
    text-shadow: 2px 2px 2px #000000;
    color: transparent;
}

.gradient-shadow:after {
    content: attr(title); /* Pulls the text from the 'title' attribute to make the shadow */
}

And then in your HTML:

<h1 class="gradient-shadow" title="Hello World"><div>Hello World</div></h1>

Just make sure that the text in the <div> matches the text in the title attribute.

Here is a Codepen example of this method: https://codepen.io/mprewitt/pen/gexypd

Michael
  • 63
  • 1
  • 6
1

These answers helped me a lot in getting to my final result. Thank you.

So I figured I would share it. Seeing the colour of my text is light, I needed a darker "border" at the top to make it pop.

Also while 'ems' are harder to work with (as opposed to px), I found that the transition of colours for the text-shadow looks a lot smoother as I wanted to make it a gradient as well :)

Works on Edge, Chrome, Vivaldi and FireFox, a little blurry though.

    <h1 class="text3d">Privacy Policy</h1>
      
      .text-3d{
      background-image:linear-gradient(to bottom,#f7eb3b 30%,#f5d839 40%,#eead34 50%, #eb9531 100%);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      filter: 
        drop-shadow(-0.015em -0.015em 0 #ffff00) 
        drop-shadow(-0.015em -0.015em 0 #bf290c) 
        drop-shadow(0 -0.005em 0 #bf290c) 
        drop-shadow(0.010em 0.025em 0 #bf290c) 
        drop-shadow(0.015em 0.030em 0 #b6240b) 
        drop-shadow(0.020em 0.035em 0 #a91d0b) 
        drop-shadow(0.025em 0.040em 0 #8d0d09) 
        drop-shadow(0.030em 0.045em 0 #830708) 
        drop-shadow(0.035em 0.050em 0 #680a07) 
        drop-shadow(0.01em 0.08em 0.01em rgba(0,0,0,0.10))
    }

3D text with gradient and gradient shadow

Marina
  • 101
  • 1
  • 7