How To Work With Linear, Radial, And Repeating CSS Gradients

Any time you can replace a bitmapped image with code you should. The code is going to weigh less and be more maintainable. That’s not to say we shouldn’t use bitmapped images, but where appropriate go with the code instead.

A few years ago designers would create large images of a solid color. I never did understand why given that a single line of code would do the same thing. We’ve reached the point where the same applies to gradients.

While they’ve been with us for a couple of years now, I’ve only recently started using css gradients in the sites I build. I’m not sure why I waited so long, but wait I did. Here and there I find them creeping into my work to style a button or to add some background texture.

As a reminder to use them more I though I’d write about them here. I also created a simple demo so you can see css gradients in action.

Chart showing browser support for css gradients

Browser Support

Since I’m saying we should use css gradients more, I should probably back that up with some data. Browser support for gradients is good. It’s not perfect, but it’s pretty good. The latest versions of all major browsers support gradients in some way. They all seem to be closing in on supporting a single standard, which is the W3c candidate recommendation from April of this year. As I’m testing only webkit browsers currently need to use a vendor prefix.

As with a lot of css, IE is a potential stumbling block as there’s no support in IE9 and below. You can use IE filters to create gradients on older versions, but you’ll need to use more than css alone to make it happen.

You might argue that suggests we should wait a bit longer, but there should never be a time where the inability to display a gradient breaks your design. If it does it says more about your design than about the gradient.

Gradients are things of progressive enhancement and not usability requirements. They should never be essential to your design working. In other words if someone using IE8 can’t see your gradient, it’s not a big deal.

Diagram of a linear gradient

How to Work with Gradients

You can use a gradient on any css property that accepts images. For example:

  • background-image — { background: linear-gradient(#fff, #555); }
  • list-style-image — { list-style-image: radial-gradient(circle, #006, #00a 90%, #0000af 100%, white 100%) ;}
  • cursor — { cursor: linear-gradient(white, gray); }

I think we sometimes see them as available only for backgrounds, but any property that can take a url to an image can also be set to display a css gradient.

There are 4 types of gradients.

  • linear-gradient
  • radial-gradient
  • repeating-linear-gradient
  • repeating-radial-gradient

I trust you know the difference between a linear and radial gradient. The repeating versions of both work similarly, except they repeat.

Gradient Lines and Color Stops

Gradients are drawn over a line that extends infinitely in both directions. They will be drawn into a box with the dimensions of the object they’re being added to, however, you can set the size of the gradient explicitly. The dimensions of the object are the default.

For example setting background-size: 100px 200px means the gradient will be drawn into 100px by 200px box even if the element itself is larger or smaller.

Color stops are points along the gradient line where we specify a solid color. In between color stops the color will transition between the two colors at each stop. This transition is the gradient we see.

[code type=css]
< color-stop> = < color> [ < percentage> | < length> ]?

For example if you set a color stop at at 20px from the left edge of an element, the color in the color stop will be solid from the edge to the 20px mark. At which point it will begin to transition to the color in the next color stop. If you only specify the color then the first stop will be at 0% and the last at 100%.

Linear gradient
linear-gradient(120deg, green, yellow);

Linear Gradients

You create a linear gradient by specifying a gradient line and then several color stops along that line.

[code type=css]
[ [ < angle> | to < side-or-corner> ] ,]?
< color-stop>[, < color-stop>]+

The first argument above [ [ < angle> | to < side-or-corner> ] ,]? specifies a gradient line. The values can take an angle or keywords. When an angle is used 0deg points up, 90deg points to the right, and so on. With keywords you use “to” and then give a location, such as to top, to right, to top right.

The default is 0deg or to top.

The second argument < color-stop>[, < color-stop>]+ takes 2 or more colors and optionally a length for each.

[code type=css]
.gradient {
background-image: linear-gradient(left, red, maroon)
background-image: linear-gradient(to left, red, maroon)

The two lines above while similar, actually have different gradient lines. The first “left” says the line starts at the left. The second “to left” says the line ends at the left. Webkit browsers don’t seem to honor the “to” keyword at the moment, though it works fine with other browsers.

We should still use vendor prefixes. The latest versions of all but webkit browsers no longer need them, but go a few versions back and they do. We should also provide a default fallback color and a fallback gradient image. Complete code for setting a linear gradient looks like the following

[code type=css]
.gradient {
background-color: maroon;
background-image: url(images/fallback-gradient.png);
background-image: -webkit-linear-gradient(left, red, maroon);
background-image: -moz-linear-gradient(left, red, maroon);
background-image: -ms-linear-gradient(left, red, maroon);
background-image: -o-linear-gradient(left, red, maroon);
background-image: linear-gradient(left, red, maroon);

Note: Webkit previously used a different syntax (-webkit-gradient), which I didn’t include above. You might want to include it in the stack just above the current webkit line, depending on how many versions back you need to support.

[code type=css]
background-image: -webkit-gradient(linear, left, right from(red), to(maroon));

You aren’t limited to only using two colors. You could set a linear gradient with more than two color stops like the following:

[code type=css]
background-image: linear-gradient(left, orange, red 33%, maroon 67%, purple);

However, I’ve noticed that additional color stops beyond two often don’t transition as nicely. There’s usually a point (the color stop) where you see a solid band of a color.

Radial gradient
radial-gradient(circle, yellow, orange 125px, red);

Radial Gradients

Radial gradients emerge from a single point and you create them by setting a shape, size, and position.

[code type=css]
[ [ < shape> || < size> ] [ at < position> ]? , |
at < position>,
< color-stop> [ , < color-stop> ]+

  • Position — determines the center of the gradient. You use keywords to set it like top left or bottom right. The default is center.
  • Shape — can be a circle or an ellipse. The default is circle.
  • Size — determines the size of the ending shape, which can be closest-side, farthest-side, closest-corner, farthest-corner. You set size with a length and percent. Length sets the radius and percentage sets the location of the color stop.

When you have an ellipse you set multiple sizes.

[code type=css]
[< length> | < percentage>]{2}

The first set of values are the horizontal and the second set are the vertical.

[code type=css]
radial-gradient(2em 5em ellipse at top left, tan 125px, brown 450px);

As with the “to” keyword, I haven’t had any luck getting webkit browsers to recognize the “at” keyword. Otherwise the css above works across browsers.

[code type=css]
.gradient-4 {
background-color: red;
background-image: url(images/fallback-gradient.png);
background-image: -webkit-radial-gradient(circle, yellow, orange 125px, red);
background-image: -moz-radial-gradient(circle, yellow, orange 125px, red);
background-image: -ms-radial-gradient(circle, yellow, orange 125px, red);
background-image: -o-radial-gradient(circle, yellow, orange 125px, red);
background-image: radial-gradient(circle, yellow, orange 125px, red);

The code above should produce a radial gradient you see in the image above. It transitions from yellow to orange to red and its shape should be a circle with a center point that matches the center of the element.

Repeating linear gradient
repeating-linear-gradient(30deg, red, brown 10px, yellow 25px);

Repeating gradients

We have 2 types of repeating gradients

  • repeating-linear-gradient
  • repeating-radial-gradient

They take the same values as above, but the color stops are repeated indefinitely in both directions. Here’s an example of a repeating-linear gradient.

[code type=css]
.gradient-5 {
background-image: -webkit-repeating-linear-gradient(30deg, red, brown 10px, yellow 25px);
background-image: -moz-repeating-linear-gradient(30deg, red, brown 10px, yellow 25px);
background-image: -ms-repeating-linear-gradient(30deg, red, brown 10px, yellow 25px);
background-image: -o-repeating-linear-gradient(30deg, red, brown 10px, yellow 25px);
background-image: repeating-linear-gradient(30deg, red, brown 10px, yellow 25px);

The pattern (seen in the image above) will repeat along the entire gradient line. With even minimal variation of the above values you can create some very different and interesting patterns.

One oddity I’ve noticed is that where Firefox and Opera treat the angle above as 30 degrees from the horizontal, webkit browsers treat it as 30 degrees from the vertical. Compare how gradient 5 in the demo looks in a webkit and non-webkit browser to see the difference.

Here’s an example of a radial-gradient.

[code type=css]
.gradient-6 {
background-image: -webkit-repeating-radial-gradient(orange, purple 20px, orange 40px);
background-image: -moz-repeating-radial-gradient(orange, purple 20px, orange 40px);
background-image: -ms-repeating-radial-gradient(orange, purple 20px, orange 40px);
background-image: -o-repeating-radial-gradient(orange, purple 20px, orange 40px);
background-image: repeating-radial-gradient(orange, purple 20px, orange 40px);

Above I stuck with 2 colors, but you can certainly add more and again with even slight variation you can achieve a lot different and interesting results.

Repeating radial gradient
repeating-radial-gradient(orange, purple 10px, orange 50px);


If you aren’t using css gradients yet, now is as good a time as any to start. This post is as much to remind me as it is to remind you. Once again check out the simple demo I created and even better experiment on your own.

Browser support is more than adequate and we aren’t dealing with design critical elements in gradients. And if you absolutely must have a gradient you can always set a fallback image so there really is no excuse.

Gradients are pretty easy to work with. The biggest hassles at the moment are probably the vendor prefixes and slight differences in how browsers honor the standard, but we should all be used to these kind of issues by now.

Browsers are moving toward adopting the latest spec and only webkit browsers still require a vendor prefix in their latest version so hopefully this hassle won’t exist for too much longer.

Do you use css gradients? If so how have they worked for you? If not, what’s keeping you from using them?

« »

Download a free sample from my book, Design Fundamentals.


  1. Nice piece. Sometimes I’ve problems with the way different display sizes affect gradients. A gradient as background in particular is hard adapt nicely on desktop and mobile devices because the flow of the gradient will be more or less subtle.

    • Thanks Jim. I know what you mean. I think it has to do with the specific gradient and how different the colors are on either side of it. Sometimes the transition isn’t as smooth as you’d like.

  2. Stephen, this looks extremely useful. I am a beginner at trying to use css for such things and have tried to duplicate this css code in a test site; however, I get nothing at all in the table cell where I applied this code. I am wondering if you could help by showing me how the code would be applied on a page with css? It’s something I would like to use a great deal going forward. Thanks so much!

    • Thanks Diane. Is the page in question online somewhere so I could see? If not can you place it online somewhere and send me the link?

      If I can see your code it’ll help me figure out why it might not be working.

Leave a Reply

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