Just as you can declare the background of an element to be a solid color in CSS, you can also declare that background to be a gradient. Using gradients declared in CSS, rather using an actual image file, is better for control and performance.
Gradients are typically one color that fades into another, but in CSS you can control every aspect of how that happens, from the direction to the colors (as many as you want) to where those color changes happen. Let’s go through it all.
While declaring the a solid color uses
background-color property in CSS, gradients use
background-image. This comes in useful in a few ways which we’ll get into later. The shorthand
background property will know what you mean if you declare one or the other.
Perhaps the most common and useful type of gradient is the
linear-gradient(). The gradients “axis” can go from left-to-right, top-to-bottom, or at any angle you chose.
Not declaring an angle will assume top-to-bottom:
To make it left-to-right, you pass an additional parameter at the beginning of the
linear-gradient() function starting with the word “to”, indicating the direction, like “to right”:
This “to” syntax works for corners as well. For instance if you wanted the axis of the gradient to start at the bottom left corner and go to the top right corner, you could say “to top right”:
If that box was square, the angle of that gradient would have been 45°, but since it’s not, it isn’t. If you wanted to make sure it was 45°, you could declare that:
You aren’t limited to just two colors either. In fact you can have as many comma-separated colors as you want. Here’s four:
You can also declare where you want any particular color to “start”. Those are called “color-stops”. Say you wanted yellow to take up the majority of the space, but red only a little bit in the beginning, you could make the yellow
color-stop pretty early:
We tend to think of gradients as fading colors, but if you have two color stops that are the same, you can make a solid color instantly change to another solid color. This can be useful for declaring a full-height background that simulates columns.
So far we’ve only looked at the new syntax, but CSS gradients have been around for quite a while. Browser support is good. Where it gets tricky is syntax and prefixing. There are three different syntaxes that browsers have supported. This isn’t what they are officially called, but you can think of it like:
- Old: original WebKit-only way, with stuff like from() and color-stop()
- Tweener: old angle system, e.g. “left”
- New: new angle system, e.g. “to right”
And then prefixing as well.
There is some overlap in there. For instance when a browser supports the New syntax they probably also support the older syntaxes as well, including the prefix. Best practice is: if it supports New, use New.
So if you wanted to absolute deepest possible browser support, a linear gradient might look like this:
That’s an awful lot of code there. Doing it by hand would be error-prone and a lot of work. Autoprefixer does a good job with it, allowing you to trim that amount of code back as you decide what browsers to support.
The Compass mixin can do SVG data URI’s for IE 9 if that’s important to you.
Internet Explorer (IE) 6-9, while they don’t support the CSS gradient syntax, do offer a programatic way to do background gradients
There are some considerations here on deciding to use this or not:
filteris generally considered a bad practice for performance,
background-imageoverrides filter, so if you need to use that for a fallback, filters are out. If a solid color is an acceptable fallback (
background-color), filter is a possibility
Even though filters only work with hex values, you can still get alpha transparency by prefacing the hex value with the amount of transparency from 00 (0%) to FF (100%). Example:
rgba(92,47,90,1) == #FF5C2F5A
rgba(92,47,90,0) == #005C2F5A
Radial gradient differ from linear in that they start at a single point and emanate outwards. Gradients are often used to simulate a lighting, which as we know isn’t always straight, so they can be useful to make a gradient seem even more natural.
The default is for the first color to start in the (center center) of the element and fade to the end color toward the edge of the element. The fade happens at an equal rate no matter which direction.
You can see how that gradient makes an elliptical shape, since the element is not a square. That is the default (
ellipse, as the first parameter), but if we say we want a circle we can force it to be so:
Notice the gradient is circular, but only fades all the way to the ending color along the farthest edge. If we needed that circle to be entirely within the element, we could ensure that by specifying we want the fade to end by the “closest-side” as a space-separated value from the shape, like:
The possible values there are:
farthest-side. You can think of it like: “I want this radial gradient to fade from the center point to the __, and everywhere else fills in to accommodate that.”
A radial gradient doesn’t have to start at the default center either, you can specify a certain point by using “at __“ as part of the first parameter, like:
I’ll make it more obvious here by making the example a square and adjusting a color-stop:
It’s largely the same as
linear-gradient(), except a very old version of Opera, right when they started supporting gradients, only did linear and not radial.
But similar to linear,
radial-gradient() has gone through some syntax changes. There is, again: “Old”, “Tweener”, and “New”.
The hallmarks being:
- Old: Prefixed with
-webkit-, stuff like
- Tweener: First param was location of center. That will completely break now in browsers that support new syntax unprefixed, so make sure any tweener syntax is prefixed.
- New: Verbose first param, like “circle closest-corner at top right”
Again, I’d let Autoprefixer handle this. You write in the newest syntax, it does fallbacks. Radial gradients are more mind-bending than linear, so I’d recommend attempting to just get comfortable with the newest syntax and going with that (and if necessary, forget what you know about older syntaxes).
With ever-so-slightly less browser support are repeating gradients. They come in both linear and radial varieties.
There is a trick, with non-repeating gradients, to create the gradient in such a way that if it was a little tiny rectangle, it would line up with other little tiny rectangle versions of itself to create a repeating pattern. So essentially create that gradient and set the
background-size to make that little tiny rectangle. That made it easy to make stripes, which you could then rotate or whatever.
With repeating-linear-gradient(), you don’t have to resort to that trickery. The size of the gradient is determined by the final color stop. If that’s at 20px, the size of the gradient (which then repeats) is a 20px by 20px square.
Same with radial:
As we’ve covered, some really old browsers don’t support any CSS gradient syntax at all. If you need a fallback that is still a gradient, an image (.jpg / .png) could do the trick. The scary part with that is that some slightly-less-old browsers, that were just starting to support CSS gradients, would load the fallback image. As in, make the HTTP request for the image even though it would render the CSS gradient.
Firefox 3.5.8 did this (see screenshot), as well as Chrome 5- and Safari 5.0.1. See:
The good news is this isn’t really any issue anymore. The only offending browsers were Chrome and Safari and Chrome hasn’t done it since 6 and Safari hasn’t done it as of 5.1, going on three years ago.
- CSS Gradients
- Conical Gradients in CSS
- How To Work With Linear, Radial, And Repeating CSS Gradients - Vanseo Design
- Single Div Drawings with CSS ✩ Mozilla Hacks – the Web developer blog