I would like to use gradients heavily in a new website I'm working on. I've been wondering if it would be better to implement the gradients in CSS3 or SVG.
Typically I only need multi-stop linear gradients so both meet my needs there.
I initially assumed this was best done in CSS3, but started to question my decision and would appreciate other opinions.
My thinking thus far is that SVG (as a CSS background) may be better because:
It works in IE9
My CSS is cleaner w/o browser prefixes
Easy reuse of gradient
CSS3 may be better because:
Seems like a job for CSS
Less downloads for the client
Everything is in one place
An important consideration that I don't know the answer to is which performs better?
Is there a best practice for implementing background gradients?
According to a test performed by Lea Verou (I trust her work), CSS gradients are faster:
http://lea.verou.me/2011/08/css-gradients-are-much-faster-than-svg/
UPDATE:
You could also consider using modernizr to serve up SVG to IE9 which supports SVG backgrounds but does not support CSS gradients.
In your CSS you would just do:
.cssgradients #someElement { /* Gradient background rule. */ }
.no-cssgradients #someElement { /* SVG background rule. */ }
More info here:
http://modernizr.com
Don't make your design choices based on making IE happy. Use progressive enhancement / graded browser support and push IE to the bottom of your support list.
Choose CSS3: your website will just appear without gradients on IE, which is probably an acceptable compromise to make.
You should use http://www.colorzilla.com/gradient-editor/ to generate CSS and SVG (for IE9) both.
Example :
background: #fefcea; /* Old browsers */
/* IE9 SVG, needs conditional override of 'filter' to 'none' */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZmNlYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMWRhMzYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
background: -moz-linear-gradient(top, #fefcea 0%, #f1da36 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fefcea), color-stop(100%,#f1da36)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fefcea 0%,#f1da36 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #fefcea 0%,#f1da36 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #fefcea 0%,#f1da36 100%); /* IE10+ */
background: linear-gradient(top, #fefcea 0%,#f1da36 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefcea', endColorstr='#f1da36',GradientType=0 ); /* IE6-8 */
It automatically generate IE9 svg code
Support for full multi-stop gradients with IE9 (using SVG). Add a
"gradient" class to all your elements that have a gradient, and add
the following override to your HTML to complete the IE9 support:
<!--[if gte IE 9]>
<style type="text/css">
.gradient {
filter: none;
}
</style>
<![endif]-->
I have chosen to implement my linear gradients in svg as I can do it once, I am of course only supporting modern browsers.
This is the SVG, I only need to describe it once. I am not sure if there is a way to define the x1y1 and x2 y2 co-ordinates using css. happy to be proven wrong.
So if CSS can not implement a gradient with x1y1 x2y2 co-ordinates I guess this is an advantage of using svg linear gradients.
the following code can be taken straight of out inkscape.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 200 200">
<defs>
<linearGradient id="grad1" x1="26.3" y1="0.2" x2="26.5" y2="3.9" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#0284a4;stop-opacity:0.9" />
<stop offset="1" style="stop-color:#0284a5;stop-opacity:1" />
</linearGradient>
</defs>
<path id="skylevel10" fill="url(#grad1)" d="m 0 -0 201 0 0 6.7 c 0 0 -29.8 1.2 Z"/>
</svg>
Related
I'm hoping to achieve a cross browser gradient, if you inspect the anchor at the top right corner running inline with the branding of my mobile site it has been styled with the prefix moz for Firefox:
www.test-bed.co.uk/mobile/
background: -moz-linear-gradient(center top , #4A4A4A, #2C2C2C) repeat scroll 0 0 transparent;
May I ask is there is a similar way to achieve a cross browser gradient solution with the IE, Opera and webkit prefixes?
An online tool that automates CSS gradient rule generation for all modern browsers: little link.
But generically, here's the main syntax:
background: #color; /*fallback*/
background: -moz-linear-gradient(...);/*Firefox*/
background: -webkit-gradient(...);/*Chrome + Safari*/
background: -webkit-linear-gradient(...);/*Another Chrome + Safari*/
background: -o-linear-gradient(...); /*Opera*/
background: -ms-linear-gradient(...); /*IE10+*/
background: linear-gradient(...); /*W3C standards*/
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#color', endColorstr='#color',GradientType=0); /*IE6-9*/
Take a look at CSS3 Please. I personally like their indentation style.
.box-gradient {
background-color: #444444;
background-image: -webkit-gradient(linear, left top, left bottom, from(#444444), to(#999999)); /* Safari 4+, Chrome */
background-image: -webkit-linear-gradient(top, #444444, #999999); /* Chrome 10+, Safari 5.1+, iOS 5+ */
background-image: -moz-linear-gradient(top, #444444, #999999); /* Firefox 3.6-15 */
background-image: -o-linear-gradient(top, #444444, #999999); /* Opera 11.10-12.00 */
background-image: linear-gradient(to bottom, #444444, #999999); /* Firefox 16+, IE10, Opera 12.50+ */
}
As you can see, there is no -ms- prefix needed since IE10 supports the W3C syntax right away. Please make sure that you use the correct W3C syntax for linear-gradient()!
If you are using firefox as a browser. then you may want to use the addon called colorzilla. It is a nice tool that comes with options like Color picker, Eye Dropper, Pallette browser, CSS gradient generator, web page DOM code Analyzer , inspect Last element as well as zoom.
However you can generator css gradient'sat the folllowing link:
http://www.colorzilla.com/gradient-editor/
I have been pulling my hair out trying to get the shadows to work on IE... They are working fine in chrome, safari, and firefox! Does someone have experience with this subject? I put the site up so you can see the full code and output.
Test Site
I am using lesscss, so maybe that is my issue? I hope not!!! I am also using the IE CSS3 Fix, ie-css3.htcThe code I am using is as follows... I was attempting to do this without the htc, but with no luck.. at least the htc got my background gradients to work in IE... before it was showing only blue-black, the default Microsoft background gradient colors.
predefine.less
.RUNgradient(#COLOR: #CLR1){
#CLRL:lighten(#COLOR, 10%);
#CLRD:darken(#COLOR, 10%);
background-color: #CLRL;
background-repeat:repeat-x;
background-image: -khtml-gradient(linear, left top, left bottom, from(#CLRL), to(#CLRD));
background-image: -moz-linear-gradient(top, #CLRL, #CLRD);
background-image: -ms-linear-gradient(top, #CLRL, #CLRD);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #CLRL), color-stop(100%, #CLRD));
background-image: -webkit-linear-gradient(top, #CLRL, #CLRD);
background-image: -o-linear-gradient(top, #CLRL, #CLRD);
background-image: linear-gradient(top, #CLRL, #CLRD);
behavior: url(css/ie-css3.htc);
}
styles.less
div.wrapper{
width:500px;
margin:25px auto;
padding: 10px 25px;
text-align:center;
.RUNgradient;
.RUNshadow;
p{
font:24px #HEADERFONT;
color:#ffffff;
.RUNtextshadow;
}
}
Filters are the answer! Almost...
For the gradient,
filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorStr="#CLRL~", EndColorStr="#CLRD~")";
And for the shadows,
filter: ~"progid:DXImageTransform.Microsoft.shadow(color="#SCLR~", Direction="#DIR~", Strength="#STR~")";
Only thing left is changing the direction in a way to have the shadow visible all around the element, not just to one side.
Solution
After researching Microsoft Filters, I figured out how to get a similar effect. The corners are a bit rough for my liking, but this is MUCH closer than before!
This is the shadow filer I used...
.RUNshadow(#BLURRING:10px){
#SCLR:#111111;
#DIR:225;
#DIR2:45;
#DIR3:135;
#DIR4:315;
#STR:4;
box-shadow: 0px 1px #BLURRING #111111;
-moz-box-shadow: 0px 1px #BLURRING #111111;
-webkit-box-shadow: 0px 1px #BLURRING #111111;
filter: ~"progid:DXImageTransform.Microsoft.shadow(color="#SCLR~", Direction="#DIR2~", Strength="#STR~")
progid:DXImageTransform.Microsoft.shadow(color="#SCLR~", Direction="#DIR~", Strength="#STR~")
progid:DXImageTransform.Microsoft.shadow(color="#SCLR~", Direction="#DIR3~", Strength="#STR~")
progid:DXImageTransform.Microsoft.shadow(color="#SCLR~", Direction="#DIR4~", Strength="#STR~")";
}
I have been pulling my hair out trying to get the shadows to work on IE... They are working fine in chrome, safari, and firefox! Does someone have experience with this subject?"
Yeah, that's normal. Most people don't bother. Remember to ask yourself, Do Websites Need To Look Exactly The Same In Every Browser?
If you really want this, you'll have to use the gradient filter for IE. Add the following style to your RUNgradient class:
filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorStr="#CLRL~", EndColorStr="#CLRD~")";
For both of them you can use IE filters.
You can use the gradient filter for gradients and the Shadow filter for shadows. The gradient filter works very well, the shadow filter looks really bad.
You can read in the documentation of the filters how to use them. But if you want to do it automatic you need see how CSS3 please is dealing with the filters and convert gradients to IE filter gradients.
You need to add these lines to the style tag for making this to work in IE,
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#444444', endColorstr='#222222'); /* IE6 & IE7 */
-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#444444', endColorstr='#222222')"; /* IE8 */
Sample code Snippet:
.ms-viewheadertr ms-vhltr
{
background: #222 ;/when gradients doesn't fill it fills the color/
background: -webkit-linear-gradient(#444, #222);/* For Safari 5.1 to 6.0 */
background: -moz-linear-gradient(#444, #222);/* For Firefox 3.6 to 15 */
background: -o-linear-gradient(#444, #222);/* For Opera 11.1 to 12.0 */
background: linear-gradient(#444, #222);/* Standard syntax */
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#444444', endColorstr='#222222'); /* IE6 & IE7 */
-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#444444', endColorstr='#222222')"; /* IE8 */
}
I am working on a CSS-based drop-down menu. It works fine until I add gradient to elements. Than something breaks in IE and when I hover over <li> items in sub-menu the menu box disappears.
Here's the code I use to add gradient and make it cross-browser compatible:
background-color: #c1ddf4; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c1ddf4', endColorstr='#ffffff', GradientType=0); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #c1ddf4), color-stop(100%, #ffffff));/* for webkit browsers */
background: -moz-linear-gradient(top, #c1ddf4, #ffffff); /* for firefox 3.6+ */
background-image: -o-linear-gradient(#c1ddf4, #ffffff);
Please see the following examples:
OK (without gradient) vs. NOT OK (with gradient)
The IE filter will break certain functionality when applied to elements. My suggestion is to use a horizontally tiled gradient image for IE, either by using a CSS hack, an IE-only style sheet, or targeting it using Modernizr.js.
The truly proper way would be to use Modernizr, then write this CSS:
.no-cssgradients li {
background: url(gradient.png) repeat-y;
}
That way, any browser that doesn't support CSS gradients (not just IE) will get served the image instead.
I would like to get a gradient in CSS (perhaps through Compass) that works in every major browser, including IE7+. Is there an easy way to do this (without writing a lot of code, and without a custom image file)?
I looked at Compass's gradient mixin, but it does not work with Internet Explorer.
Any ideas? (It does not need to be Compass -- I am happy install something else.)
Edit: What I am trying to get is some framework (like Compass?) that generates code like what Blowsie posted that's been tested across browsers. Basically like the Compass gradient mixin I mentioned, but with IE support. (I am a bit wary of just rolling my own SCSS mixin and pasting in blocks like Blowsie's code, because I haven't tested it and do not have the resources to do so.)
I just noticed that the current Compass beta (0.11.beta.6) has support for generating IE gradients in the compass/css3/images module (which supersedes the previous gradient module), so you can generate your gradients with a total of two short commands:
#import "compass/css3/images";
#import "compass/utilities/general/hacks"; /* filter-gradient needs this */
.whatever {
/* IE; docs say this should go first (or better, placed in separate IE-only stylesheet): */
#include filter-gradient(#aaaaaa, #eeeeee);
/* Fallback: */
background: #cccccc;
/* CSS 3 plus vendor prefixes: */
#include background(linear-gradient(top, #aaaaaa, #eeeeee));
}
This generates the following slew of CSS:
.whatever {
*zoom: 1;
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFAAAAAA', endColorstr='#FFEEEEEE')";
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFAAAAAA', endColorstr='#FFEEEEEE');
background: #cccccc;
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #aaaaaa), color-stop(100%, #eeeeee));
background: -moz-linear-gradient(top, #aaaaaa, #eeeeee);
background: -o-linear-gradient(top, #aaaaaa, #eeeeee);
background: linear-gradient(top, #aaaaaa, #eeeeee);
}
I guess I would have preferred to have the IE and non-IE gradient code in one call, but since IE's DXImageTransform gradient function is pretty limited, that is probably not possible.
The code I use for all browser gradients..
background: #0A284B;
background: -webkit-gradient(linear, left top, left bottom, from(#0A284B), to(#135887));
background: -moz-linear-gradient(top, #0A284B, #135887);
background: -o-linear-gradient(#0A284B, #135887);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0A284B', endColorstr='#135887');
zoom:1;
You will need to specify a height or zoom:1 to apply hasLayout to the element for this to work in ie
While gradients are of limited complexity, they're complex enough to require what you would consider "lots of code".
Consider:
starting colour, ending colour and the hexadecimal math required to transition between one and the other
The number of "steps"
The width/height of each step
Since there is no pure CSS way of doing this, it means rendering HTML, one element for each colour/step, without messing up your existing HTML
So, no, without a plug-in that does all of this for you, it would require a bit of code, or an image.
Does anyone know the vendor prefix for gradients within IE9 or are we still supposed to still be using their proprietry filters?
What I've got for the other browsers is:
background-image: -moz-linear-gradient(top, #444444, #999999); /* FF3.6 */
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #444444),color-stop(1, #999999)); /* Saf4+, Chrome */
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#444444', EndColorStr='#999999'); /* IE6,IE7 */
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#444444', EndColorStr='#999999')"; /* IE8 */
As a bonus does anyone know Opera's vendor prefix as well?
Looks like I'm a little late to the party, but here's an example for some of the top browsers:
/* IE10 */
background-image: -ms-linear-gradient(top, #444444 0%, #999999 100%);
/* Mozilla Firefox */
background-image: -moz-linear-gradient(top, #444444 0%, #999999 100%);
/* Opera */
background-image: -o-linear-gradient(top, #444444 0%, #999999 100%);
/* Webkit (Safari/Chrome 10) */
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #444444), color-stop(1, #999999));
/* Webkit (Chrome 11+) */
background-image: -webkit-linear-gradient(top, #444444 0%, #999999 100%);
/* Proposed W3C Markup */
background-image: linear-gradient(top, #444444 0%, #999999 100%);
Source: http://ie.microsoft.com/testdrive/Graphics/CSSGradientBackgroundMaker/Default.html
Note: all of these browsers also support rgb/rgba in place of hexadecimal notation.
The best cross-browser solution is
background: #fff;
background: -moz-linear-gradient(#fff, #000);
background: -webkit-linear-gradient(#fff, #000);
background: -o-linear-gradient(#fff, #000);
background: -ms-linear-gradient(#fff, #000);/*For IE10*/
background: linear-gradient(#fff, #000);
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ffffff', endColorstr='#000000');/*For IE7-8-9*/
height: 1%;/*For IE7*/
You still need to use their proprietary filters as of IE9 beta 1.
IE9 currently lacks CSS3 gradient support. However, here is a nice workaround solution using PHP to return an SVG (vertical linear) gradient instead, which allows us to keep our design in our stylesheets.
<?php
$from_stop = isset($_GET['from']) ? $_GET['from'] : '000000';
$to_stop = isset($_GET['to']) ? $_GET['to'] : '000000';
header('Content-type: image/svg+xml; charset=utf-8');
echo '<?xml version="1.0"?>
';
?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<defs>
<linearGradient id="linear-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#<?php echo $from_stop; ?>" stop-opacity="1"/>
<stop offset="100%" stop-color="#<?php echo $to_stop; ?>" stop-opacity="1"/>
</linearGradient>
</defs>
<rect width="100%" height="100%" fill="url(#linear-gradient)"/>
</svg>
Simply upload it to your server and call the URL like so:
gradient.php?from=f00&to=00f
This can be used in conjunction with your CSS3 gradients like this:
.my-color {
background-color: #f00;
background-image: url(gradient.php?from=f00&to=00f);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f00), to(#00f));
background-image: -webkit-linear-gradient(top, #f00, #00f);
background-image: -moz-linear-gradient(top, #f00, #00f);
background-image: linear-gradient(top, #f00, #00f);
}
If you need to target below IE9, you can still use the old proprietary 'filter' method:
.ie7 .my-color, .ie8 .my-color {
filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ff0000", endColorStr="#0000ff");
}
Of course you can amend the PHP code to add more stops on the gradient, or make it more sophisticated (radial gradients, transparency etc.) but this is great for those simple (vertical) linear gradients.
The code I use for all browser gradients:
background: #0A284B;
background: -webkit-gradient(linear, left top, left bottom, from(#0A284B), to(#135887));
background: -webkit-linear-gradient(#0A284B, #135887);
background: -moz-linear-gradient(top, #0A284B, #135887);
background: -ms-linear-gradient(#0A284B, #135887);
background: -o-linear-gradient(#0A284B, #135887);
background: linear-gradient(#0A284B, #135887);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0A284B', endColorstr='#135887');
zoom: 1;
You will need to specify a height or zoom: 1 to apply hasLayout to the element for this to work in IE.
Update:
Here is a LESS Mixin (CSS) version for all you LESS users out there:
.gradient(#start, #end) {
background: mix(#start, #end, 50%);
filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorStr="#start~", EndColorStr="#end~")";
background: -webkit-gradient(linear, left top, left bottom, from(#start), to(#end));
background: -webkit-linear-gradient(#start, #end);
background: -moz-linear-gradient(top, #start, #end);
background: -ms-linear-gradient(#start, #end);
background: -o-linear-gradient(#start, #end);
background: linear-gradient(#start, #end);
zoom: 1;
}
Opera will soon start having builds available with gradient support, as well as other CSS features.
The W3C CSS Working Group is not even finished with CSS 2.1, y'all know that, right? We intend to be finished very soon. CSS3 is modularized precisely so we can move modules through to implementation faster rather than an entire spec.
Every browser company uses a different software cycle methodology, testing, and so on. So the process takes time.
I'm sure many, many readers well know that if you're using anything in CSS3, you're doing what's called "progressive enhancement" - the browsers with the most support get the best experience. The other part of that is "graceful degradation" meaning the experience will be agreeable but perhaps not the best or most attractive until that browser has implemented the module, or parts of the module that are relevant to what you want to do.
This creates quite an odd situation that unfortunately front-end devs get extremely frustrated by: inconsistent timing on implementations. So it's a real challenge on either side - do you blame the browser companies, the W3C, or worse yet - yourself (goodness knows we can't know it all!) Do those of us who are working for a browser company and W3C group members blame ourselves? You?
Of course not. It's always a game of balance, and as of yet, we've not as an industry figured out where that point of balance really is. That's the joy of working in evolutionary technology :)
I understand that IE9 still won't be supporting CSS gradients. Which is a shame, because it's supporting loads of other great new stuff.
You might want to look into CSS3Pie as a way of getting all versions of IE to support various CSS3 features (including gradients, but also border-radius and box-shadow) with the minimum of fuss.
I believe CSS3Pie works with IE9 (I've tried it on the pre-release versions, but not yet on the current beta).
Not sure about IE9, but Opera doesn’t seem to have any gradient support yet:
http://www.opera.com/docs/specs/presto26/#css
No occurrence of “gradient” on that page.
There’s a great article by Robert Nyman on getting CSS gradients working in all browsers that aren’t Opera though:
http://robertnyman.com/2010/02/15/css-gradients-for-all-web-browsers-without-using-images/
Not sure if that can be extended to use an image as a fallback.
As of version 11, Opera supports linear gradients with the -o- vendor prefix. Chris Mills wrote a Dev.Opera article about it: http://dev.opera.com/articles/view/css3-linear-gradients/
Radial gradients are still in the works (both in the spec, and within Opera).
Use an Gradient Generator - and everything will be perfect ;)
http://www.colorzilla.com/gradient-editor/