Monday, January 2, 2012

CSS3 Linear Gradients

It’s been a while since we posted anything particularly technical to the Web Directions blog, but that’s something we plan on changing. Here’s the first in a series of technical articles on CSS3 features (along with tools to help you lean and use them).
We’re starting with linear gradients. We’ll take a look at where they come from, how to use them, and the current level of browser support. Ironically although webkit introduced gradients, until version 5.1, Safari has supported a different syntax from that described here — so, if you are using a version of Safari other than 5.1 (currently in beta) you won’t be able to see the examples.

A little history

webkit first introduced the proposed gradient feature of CSS3 way back in 2008, enabling the browser to generate a gradient to be used where images are in CSS — most commonly as a background image, but also potentially for list items images, border-​​images, and generated content. Firefox 3.6 followed suit, but introduced a couple of challenges. It introduced a different syntax (now adopted as the proposed CSS3 gradient syntax), and gradients were only available as background images (this restriction is still true today). Not surprisingly, the webkit based Chrome supports gradients, as does Opera since version 11.1 (though only linear gradients (more in a second) are currently supported). What of Internet Explorer you ask? Well, version 10 in fact supports gradients!
Don’t be too alarmed by the two different syntaxes — webkit now supports the same syntax as other browsers, as of Safari 5.1 (we’ll also look at how to ensure maximum browser compatibility in a moment as well).

How they work

Enough history, let’s play with them. There are in fact, as mentioned above, two kinds of gradients (linear and radial gradients). In this article, we’ll focus on linear gradients — and return to radial gradients in an upcoming article.
Gradients aren’t properties (like color), but are a computed values of CSS, something you might not be too familiar with. We use them where we’d typically use a url pointing to an image (most commonly background-image). In essence, the browser generates an image and uses that.
Here’s one in action
OK, so I’ve cheated a little and added a bit more style, but that subtle gradient is all done with CSS. Try increasing the text size — and see how the background gradient continues to fill the element.
Here’s what the CSS looks like.
background-image: linear-gradient(top, #eff6fb, #d3e4f3 68%);
(I said don’t panic for a reason — if you are interested in the underlying concepts, read on. But if you are a more hands-​​on kind of learner, simply head to the gradient tool I’ve built, and start playing.)
The linear-​​gradient starts at the top of the element (we’ll see shortly there are other places it can start) and runs vertically to the bottom of the element. At the top, the initial color is #eff6fb. At 68% down the element, the color is #d3e4f3, and the browser generates a gradient image that smoothly transitions from #eff6fb to #d3e4f3. From 68% down the element, to its bottom, the color is a solid #d3e4f3.
gradient in action
BTW, “#d3e4f3 68%” is called a color stop — and gradients can potentially have many stops.
Before we go on, let’s recap. A gradient is value, starting with the keyword linear-gradient, and then containing a number of values inside parentheses. These values specify the direction of the gradient (in this case from top to bottom), a starting color, and then one or more color stops. A color stop is a color value, with an optional length or percentage value (for example, we can have a stop at 1em, 20px and so on).
Here, for example is a gradient with numerous stops
background-image: linear-gradient( left, #FF0000, #FFA500 13.0%,#FFFF00 26.0%,#0000FF 39.0%,#008000 52.0%,#4B0082 65.0%,#EE82EE 78.0%)

The gradient direction

We specify the direction of the gradient in one of two ways. We can specify where it starts horizontally with the keywords left and right, and vertically with the keywords top and bottom. Let’s look at each of these (just follow the link to see each)
We can also combine keywords — to create diagonal gradients from the top left, bottom left, top right and bottom right:
But gradients would be pretty dull if they could only be horizontal, vertical, or diagonal, so there’s a second way to specify the gradient direction-​​degrees. (You use keywords or degrees, not both together).
To specify a gradient angle, we use the format 90deg (0deg has the gradient start at the left, 90deg at the bottom, 180deg at the right, and 270deg at the top. So, we can think of degrees as going counter-​​clockwise from 9 o’clock (0deg).)
As usual, the simplest way to understand this is to play with it — so head over to the gradient tool I’ve built expressly for this purpose, and vary the angle to see what happens.
background-image: linear-gradient(126deg, #FF0000, #FFA500 13.0%,#FFFF00 26.0%,#0000FF 39.0%,#008000 52.0%,#4B0082 65.0%,#EE82EE 78.0%)

Repeating gradients

Is your head full of complex stuff yet — color stops, gradient angles, and so on? Well, let’s add to that, with repeating gradients. That’s right, you can repeat a gradient. Here’s how that works. If your last color stop is before the “end” of the element (so, for example if the gradient goes from left to right, the last stop is less than 100% of the width of the element), then the gradient will be repeated from the location of the last color stop. If we have a simple gradient like this
background-image: linear-gradient(0deg, #FF0000, #FFA500 50%)
then we change the value name from linear-gradient to repeating-linear-gradient, then we’ll have the gradient repeat itself from 50% to 100% of the width of the element, like so
background-image: repeating-linear-gradient(0deg, #FF0000, #FFA500 50%)

Forget the math, here’s a tool

As I mentioned above, there’s no need to remember all the syntax and concepts — as I’ve developed the linear gradient tool to make life easier for you. (In fact I significantly overhauled the version I developed something like 2 years ago, to provide widespread browser support, and support the new syntax more fully.)
There are some other good gradient tools out there as well, including ColorZilla. I’ve designed this (and my other CSS3 tools) to closely follow the concepts of CSS gradients, to be as much a tool for learning, as for producing fine looking gradients.
It also has some additional features you might like.
  • You can tweet a link to a gradient you’ve created by simply clicking a button
  • You can copy the url of your gradient, and send it to someone via email, put it in a link (like I’ve done for many of these examples) or otherwise share it
  • Via the magic of HTML5 localStorage, it remembers your most recent gradient, and other settings next time you visit
  • It adds vendor prefixes for all modern browsers as an option
  • It adds the start color as a background color for older browsers
  • There’s a related tool for creating old style Safari gradients
  • It provides up to the minute browser compatibility information
  • It looks really pretty, all thanks to CSS gradients of course
So give it a go, and tell me what you think.

Backwards compatibility

Now, you might be asking yourself, what about the backwards compatibility issues with older browsers and are there any accessibility challenges in using gradients? Luckily, gradients are really straightforward to use in an accessible, backwards compatible way, across multiple browsers provided you keep a couple of things in mind.
Firstly, ensure you have a background color (or image) for the element to ensure color contrast with the text. Where gradients aren’t supported, the browser will ignore them, and use the color or image.
At present, all browsers require vendor specific extensions for gradient values. The gradient tool will create those for you. Make sure that you include a gradient value with no vendor extensions, and make this the last of the properties you specify (as we know, if CSS, the last property trumps earlier ones in the rule). So for example
background-color:#AB1364;
background-image: -moz-linear-gradient(114deg, #AB1364, #52FF26 11%);
background-image: -webkit-linear-gradient(114deg, #AB1364, #52FF26 11%);
background-image: -o-linear-gradient(114deg, #AB1364, #52FF26 11%);
background-image: -ms-linear-gradient(114deg, #AB1364, #52FF26 11%);
background-image: linear-gradient(114deg, #AB1364, #52FF26 11%)
For older versions of Safari, we’ll need to have a different background-image property. Not only is the syntax different, the concepts are too, so you might like to use my old style CSS3 Linear Gradient generator to help you out.
And, wth the exception of webkit, gradients are only applicable to backgrounds, (webkit browsers support gradients anywhere images are used.)

Browser Support Notes

A quick summary of current browser support for CSS Linear Gradients.
  • Safari 4 introduced linear gradients, though as noted with a different syntax from that detailed here. The vendor prefix –webkit– is required for gradients (e.g. –webkit-​​linear-​​gradient)
  • Safari 5.1 introduces the syntax detailed here, as well as continuing to support the older style syntax. Again, the –webkit-​​vendor prefix is required.
  • Firefox 3.6 was the first browser to support the current gradient syntax. The –moz– prefix is required, and it’s currently only supported on backgrounds.
  • Chrome 10 and up (and probably earlier versions) supported the syntax for gradients detailed here. The –webkit– prefix is required.
  • Opera 11.1 introduced linear gradients, once again with the vendor prefix, –o– required. Currently gradients are only supported on backgrounds.
  • Internet Explorer 10 also features CSS gradients, using the prefix –ms-​​, and also only supported on backgrounds.
And just to make life easy, there is talk at the W3C CSS Working Group of changing the syntax yet again.

More links, examples, and so on

To do on the Generator

  • At present, the generator only supports hex color values. Enabling rgba and color keywords (particularly transparent) are important next steps.
  • Support for multiple background gradients on a single element, used extensively at the CSS Gradient Gallery
  • Automatic generation of older webkit style syntax.
  • Taking requests — let me know what you’d like to see

10 responses to “CSS3 Linear Gradients”:

  1. Thanks John, this clears it right up. They’re actually not that complicated when explained properly!
    Although one has to wonder why the degrees implementation starts at 9 o’clock and works anti-​​clockwise. I would have thought starting at 12 o’clock and working clockwise would have been easier to remember. Specifying margins and padding works fine that way, why use a different method?
    *shrugs*
  2. Hello John,
    Have you been following the recent debates on www-​​style? Firstly the angles are changing where 0 degrees indicates the beginning point (first color stop) of a gradient which would be positioned at the top (northern) part of a box. The WD did have for about 2 week the opposite, where 0 degrees indicated the ending point (last color stop) of a gradient. This was also affecting top and bottom which the WD was saying were the referencing the ending points. Now it’s been marked as a CSS issue as mentioned two days ago on the www-​​style mailing list and in the WD (in red text).
    Another thing that could be happening is how gradients with color with alpha transparency work. Some want interpolation in premultiplied space where others (one being me) are saying that gradients should work as they do now which is that interpolation happens in un-​​premultiplied space. I am currently working with an implementer to explore the consequence of such a change since they are testing in an implementation (browser) that supports interpolation in premultiplied space. Certain gradients are broken (look wrong).
    I tried to alert other authors recently but no one seems to know what I am talking about. The truth is, only a few understand the difference between premultiplied space and un-​​premultiplied space. I can explain it quickly but it’s very hard to do in typed words.
    I myself would like the issued resolved since I have been working on gradients transitions (animations) where some color stops are partly transparent. Such a demo.
    • By:Joni
    • July 5th, 2011
    Also rememeber that if you put these to body/​html element (or any big element), older machines doesn’t like that so much.. :) it slows down scrolling heavily. Specially with fixed background. I haven’t tested with small elements, like buttons etc.
  3. […] 19, 2011 Leave a response Getting your head around CSS3 radial gradientsWe recently took a detailed look at linear gradients in CSS3. If you’ve not read that, you might like to spend a few minutes doing so, as the concepts are […]
    • By:fjpoblam
    • September 13th, 2011
    Good article, John. I’ve been using the *old* (proprietary) formats for quite awhile as my main website background. Before that, I was using a simple tiled 2px by 800px gradient.
    Perhaps I misunderstood, but I *thought* your implication was that the new (5.1+) Safari supported the new format.
    FWIW, I tried your new format, on MacOSX 10.6.8 (Snow Leopard), in both Safari 5.1 (6534.50) and the latest Webkit nightly (r94932), with no luck. (My website is coded in “HTML5”, if that makes a difference.) Therefore, I’ve returned to the proprietaries: –moz, –o, and –webkit.
    It is curious that your demo shows up correctly in both Safaris, though I didn’t take the time to try it out in FF, Chrome, Camino, or Opera. I don’t know whether you’re using the new spec “behind the scenes” or just an illustrative graphic.
    • By:John
    • September 17th, 2011
    Safari 5.1 supports both the old and new formats. but AFAIK, you sat still need –webkit– for Safari 5/.1 and the new formats
  4. […] make rotating an element easy.The rotate function takes an angle value. If you’ve worked with CSS linear gradients, in particular the newer syntax, then you’ll have seen angle units before. There are several ways […]
  5. […] recently took a detailed look at linear gradients in CSS3. If you’ve not read that, you might like to spend a few minutes doing so, as the concepts are […]
  6. […] CSS3 Linear Gradients – John Allsopp […]
  7. […] CSS3 Linear Gradients | Web Directions (webdirections​.org) LD_AddCustomAttr(“AdOpt”, “1”); LD_AddCustomAttr(“Origin”, “other”); LD_AddCustomAttr(“theme_bg”, “ffffff”); LD_AddCustomAttr(“theme_border”, “f1f1f1”); LD_AddCustomAttr(“theme_text”, “555555”); LD_AddCustomAttr(“theme_link”, “059bff”); LD_AddCustomAttr(“theme_url”, “e5f2bf”); LD_AddCustomAttr(“LangId”, “1”); LD_AddCustomAttr(“Autotag”, “science”); LD_AddCustomAttr(“Autotag”, “technology”); LD_AddCustomAttr(“Tag”, “web-​​development”); LD_AddCustomAttr(“Tag”, “css”); LD_AddCustomAttr(“Tag”, “css-​​techniques”); LD_AddCustomAttr(“Tag”, “css3”); LD_AddCustomAttr(“Tag”, “css3-​​gradients”); LD_AddCustomAttr(“Tag”, “gradients”); LD_AddCustomAttr(“Tag”, “website-​​design”); LD_AddSlot(“wpcom_below_post”); LD_​GetBids(); Share this:FacebookStumbleUponDiggTwitterLike this:LikeBe the first to like this post. […]

No comments: