The top 10 CSS3 techniques

Denise Jacobs reveals her top tips on how to use the most exciting CSS3 properties - and provide fallbacks for older browsers

This article originally appeared in issue 210 of .net magazine - the world's best-selling magazine for web designers and developers.

While the following list does not include all of the great new properties in the CSS3 specification, this selection of the top 10 will give you a great start with your front-end coding projects. They’ll save you a lot of time and effort. Note: with the exception of @font-face, neither IE6, 7 nor 8 (from here on referred to as “the older IEs”) support any of the CSS3 properties. IE9 supports several properties and will be indicated.


1. @font-face

@font-face allows for fonts to be downloaded from a web server to the user’s computer to correctly render a given font. The syntax is:

@rule-name {font-family: "Fontname";src: url(fontfilename.ext) format('formatname');}
Because @font-face has been around for a while, it’s one of the only CSS3 features that is supported by all browsers. However, the older IEs require for the font to be in the .eot file format. The good news: IE9 now supports the .woff format. One issue to be aware of is licensing. Be sure the font you’re creating the @font-face files for actually supports being used as a web font. Another issue is the Flash of Unstyled Text (FOUT). This article by Paul Irish has several solutions:
@font-face is showcased beautifully
@font-face is showcased beautifully at
There is a true bug with the older IEs: even when an .eot file is established and is stacked correctly in the @font-face declaration, the IEs still may not render it due to being distracted by the subsequent values. To get around this, it helps to have two @font-face declarations: the first one with the .eot by itself, and then the second with the standard @font-face declarations.
There’s also a bug with WebKit browsers when applying font-weight: bold or font-style: italic to @font-face’d text: it doesn’t work. The fix: add normal to font weight, style and variant in the @ font-face declaration to set a baseline. 

The full solution

This solution incorporates a fix for the IE bug and sets a baseline for font weight and variant changes:
@font-face {font-family: 'Colaborate Light';src: url('ColabLig.eot');src: local(''), url('ColabLig.woff') format('woff'),url('ColabLig.ttf') format('truetype');font-weight:normal;font-style:normal;font-variant:normal;}

The smiley face glyph is intentional: it keeps the browser from looking for a local copy of the font and forces it to use the downloadable ones. Alternatively, to proactively code for potential Internet Explorer bugs:

@font-face {font-family: 'Colaborate Light';src: url('ColabLig.eot');font-weight:normal;font-style:normal;font-variant:normal;}@font-face {font-family: 'Colaborate Light';src: local(''), url('ColabLig.woff') format('woff'),url('ColabLig.ttf') format('truetype');font-weight:normal;font-style:normal;font-variant:normal;}
Top tool: Font Squirrel has a great @font-face kit generator that will give you the fonts in all of the formats desired plus the CSS:

2. Opacity

You can control the opacity of an element, going from fully transparent to opaque. The opacity property applies to the whole element and is inherited by all of its children unless overridden by another declaration. For more granular control of the opacity of particular elements, use RGBA colour instead. The syntax is dead simple:
opacity: <value>;
The values are from 0.0 to 1.0 (full opacity, ie, solid). Although the values can be to two decimal places (ie, .37 etc), there’s not much of a discernable difference. While the IEs do not support opacity at all, there is a Microsoft-specific filter. There are three versions. The short form of the property works on all IEs:
filter: alpha(opacity=40);
So does the extended form of the property:
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=40);
The extended form using the -ms- prefix works for IE8-9:
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=40)";
Stack order is important: -ms- filter first, filter last. According to Peter-Paul Koch of quirksmode. org, if you don’t use this order, IE8-as-IE7 won’t apply the opacity, although true IE7 and IE8 will.

The full solution

The stack is important here too:
.opacity {background-color: #3C4C55;color: #fff;opacity: 0.5;-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=20)";/* above line is IE8 only */filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20);/* above line works in IE6, IE7, and IE8 */filter: alpha(opacity=20);}



RGBA colour is one of the multiple ways you can declare colour in CSS. What makes it special is that you can also establish the transparency of the colour at the same time. The syntax for the RGBA colour notation is:
property: rgba(<r color value>, <g color value>, <bcolor value>, <opacity value>);
The color values will be 0-255, and the opacity values 0.0-1.0. All modern browsers support RGBA, including IE9. The older IEs? Not so much. One bug with the older IEs comes when using RGBA to set the background-color of an element: the colour won’t show. The solution is to use the shorthand property background instead of background-color to set the fallback colour, or to use a hexidecimal colour instead of RGBA. While that fixes the problem of the colour showing up, it doesn’t speak to the opacity of the colour. To maintain the opacity as well in the IEs, you could use gradient filter to create the colour opacity.

The full solution

Using the shorthand background property:
#sidebar{background: rgb(255, 0, 0); /* fallback color in RGB*/background: rgba(255, 0, 0, 0.3);}
Or, using the more specific background-color property:
#sidebar {background-color: #ff0000; /* fallback color inhexidecimal */background-color: rgba(255, 0, 0, 0.3);}
Or, sticking with the background-color property and adding IE filters:
.rgba {background-color: #ff0000; /* fallback color inhexidecimal. */background-color: transparent; /* transparent iskey for the filter to work in IE8. best donethrough conditional comments */background-color: rgba(255, 0, 0, 0.3);-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4CFF0000,endColorstr=#4CFF0000)";/* filter for IE8 */filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#4CFF0000,endColorstr=#4CFF0000);/* filter for older IEs */}


4. Border-radius

border-radius gives us the coveted rounded corners and is easily one of the most useful of the CSS3 properties. Using the shorthand is straightforward when you’re styling all four corners with the same values. border-radius shorthand:
border-radius: <top value>, <right value>, <bottomvalue>, <left value>;
The plot thickens when establishing values for the corners individually. The -moz- syntax allows multiple values for each position in more of a shorthand style, whereas the -webkit- syntax calls for an altered naming convention for the properties with corresponding individual values. The standard syntax is like that of WebKit. border-radius is well-supported by all modern browsers, but there’s no handy filter to fall back on for IE. One method is to serve different styles to the older IEs that incorporate an older imagebased solution for rounded corners. The simplest option is to allow the corners to be square for the IE user base and have the rounded corners as a progressive enhancement feature.

The full solution

Use the same value for all four corners:
.roundcorners {-moz-border-radius: 20px;-webkit-border-radius: 20px;border-radius: 20px;}
Different values for each corner:
.roundcorners {border: 5px solid #aaa;-moz-border-radius: 10px 5px;-webkit-border-top-left-radius: 10px;-webkit-border-top-right-radius: 5px;-webkit-border-bottom-right-radius: 10px;-webkit-border-bottom-left-radius:5px;border-radius: 10px 5px;}

Top tool: A fantastic generator for border radius is aptly named The tool quickly produces cross-browser compliant code for creating border-radius.


5. Box-shadow

Another long-awaited feature: box-shadow generates drop-shadows on elements, with no more image swapping, slicing or other shenanigans. The syntax is:

box-shadow: <position> <x-offset>, <y-offset>,<blur radius>;
  • position: the default value is outset and does not need to be stated. The other value is inset and needs to be established if desired. 
  • horizontal/x-offset: a positive value places the shadow on the right of the box; a negative value places the shadow on the left of the box. 
  • vertical/y-offset: a positive value places the shadow below the box; a negative value places the box-shadow above the box. If this third value is omitted, then the blur will be set to 0. 
  • blur radius: 0 is the sharpest, as there is no blur; higher numbers increase the blur. A measurement notation must be given. 
Naomi Atkinson's site
Naomi Atkinson Design employs both box-shadow and text-shadow at
Box-shadow is well supported by all the modern browsers, including IE9. In Firefox 4.0, the -mozprefix was dropped and is no longer necessary, but for versions 3.5 and below, the -moz- should still be used. Aside from the vendor prefixes, the syntax is the same. You can assign multiple shadows to a single element by listing the multiple property value sets. Both the dropshadow and shadow filters can be used to achieve the effect in Internet Explorer, but according to Robert Nyman of, the shadow filter creates a nicer shadow.

The full solution

.boxshadow {-moz-box-shadow: 3px 3px 10px #333;-webkit-box-shadow: 3px 3px 10px #333;box-shadow: 3px 3px 10px #333;/* For IE 8 */-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135,Color='#333333')";/* For IE 5.5 - 7 */filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135,Color='#333333');} 


6. Text-shadow

The kissing cousin to box-shadow, textshadow adds drop shadows to text, allowing for effects such as outer glow, embossed and letterpress looks. The syntax for text-shadow is identical to that of box-shadow, except that the value inset is not applicable to text-shadow. Like its box counterpart, text-shadow is also well supported by all the modern browsers and Internet Explorer 9. Also like box-shadow, you can assign multiple shadows to a single element by listing the multiple property value sets. It’s possible to get some really good effects on text that way.

In terms of graceful degradation, the shadow filter is the way to go for an Internet Explorer equivalent. Barring that, you could kick it old-school with image replacement through conditional comments if you wanted to.

The full solution

.textshadow h2 {text-shadow:1px 1px 2px rgba(48,80,82,0.8);-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=2,Direction=135, Color='#305052')";/* For IE 5.5 - 7 */filter: progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135,Color='#305052');}
  1. Top tool: There are several great CSS3 generation tools at, including ones for box-shadow and text-shadow: and


7. Gradient

Along with border-radius, gradient is one of my favourite additions to CSS3. Interestingly, gradient isn’t a property itself, but rather a value set that be can used with the properties background, border-image and list-style-image. The gradient is generated by the browser, and thus saves several steps in having to make an image in an image editor. gradient is the one property with the most variation in syntax between the browsers. I’ve created a handy little value mapping and breakdown chart for linear gradients.
Some tips to remember which syntax goes with which browser:
  • The -moz- and standard syntax notate the type of gradient before the list of values enclosed in the parentheses
  • The -moz- syntax allows for a degree value
  • The position names vary between the two browsers
  • The -webkit- syntax denotes the colour stops with from and to
Mozilla allows for an angle value, but it’s not required. An omitted angle value equals 0. At present, neither Opera nor Internet Explorer (including IE9) supports gradient. Unfortunately for Opera, the fallback will be to do what you did before: have a background image for the gradient. For the IEs, there’s a filter that will create linear gradients. Unfortunately, there’s no IE filter for radial gradients.

The full solution

.gradient {color: #fff;background: #aaaaaa url(gradient_slice.jpg) 0 0x-repeat; /*background color matches oneof the stop colors. The gradient_slice.jpg is1px wide */background-image: -moz-linear-gradient(top, #07407c, #aaaaaa);background-image: -webkit-gradient(linear,lefttop,left bottom,color-stop(0, #07407c),color-stop(1, #aaaaaa));-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#07407c',EndColorStr='#aaaaaa')";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr='#07407c', EndColorStr='#aaaaaa');}
Top tool: The gradient generation tool at is highly efficacious. Colorzilla also has a great gradient generator at


8. Multiple background images

With CSS3, you can establish multiple backgrounds for an element. Again, this is great progress from the days of using non-semantic nested elements to achieve a similar outcome. While being able to have multiple images assigned to one element was available in CSS2.1, with CSS3 they now work as layers, with the first background listed as being on “top” (closest to the user in space), and the following backgrounds stacking “beneath” the first. The syntax is easy: just list the value sets and separate them with a comma. Only the final value set in the list can have a background-color value.
background:<image> <position> <size> <repeat> <attachment> <box>,<image> <position> <size> <repeat> <attachment> <box>,<image> <position> <size> <repeat> <attachment> <box>,<image> <position> <size> <repeat> <attachment> <box> <color>;
Alternatively, establish the properties separately:
background-image: <image>, <image>, <image>, <image>;background-repeat: <repeat>, <repeat>, <repeat>,<repeat>;background-position: <position>, <position>, <position>,<position>;/* plus any background attachment and/or box properties as needed */
All modern browsers support multiple backgrounds except -- you guessed it -- the older IEs. IE9 Multiple background images supports multiple background values. By now you know the drill: you should establish a fallback image with all desired properties, so create that background declaration before the declaration that lists the multiple background value sets. Unsupportive browsers will display just one background: the first background property listed. However, according to Peter-Paul Koch, Explorer Mac will instead display the last one listed.
As for an IE filter to replicate the outcome, one exists, but it’s not sophisticated at all. You could use the AlphaImageLoader filter to load multiple images, but unfortunately, while you’ll get alpha transparency, you can’t really control the placement (which is stuck at the top left), nor the image repeat (which is stuck at none). There are other performance issues too. A final option would be to create a flattened version of the background image layers and serve that background image to the older IEs through conditional comments.

The full solution

#wrap {background: url(body-full.gif) top left no-repeat;background:url(body-top.gif) top left no-repeat,url(body-bottom.gif) bottom left no-repeat,url(body-middle.gif) left repeat-y;-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' body-top.gif',sizingMethod='scale')";filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='body-top.gif', sizingMethod='scale');zoom: 1;}
Alternatively, try this:
body {background: url(all_layers.jpg) no-repeat 0 0;background-image:url(first_layer.png),url(second_layer.png),url(third_layer.png),url(fourth_layer.png);background-repeat: no-repeat, no-repeat,no-repeat, no-repeat;background-position: 0 0, 0 50, 0 100, 0 200;-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' body-top.gif',sizingMethod='scale')";filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='body-top.gif', sizingMethod='scale');zoom: 1;}


9. Transform

Transform has a number of values that do various things: rotate, scale, skew, translate and matrix. I’ll only discuss rotate here: for full details on the rest of the transform values see The generic syntax is:

<-prefix->transform: type(<value>) type(<value>)type(<value>) type(<value>);
For rotate specifically, here’s the syntax:
<-prefix->transform: rotate(<value>)
Positive values will rotate the object clockwise to the right, and negative values will rotate the element counter-clockwise to the left. There is an IE filter that will rotate an element: the matrix filter. Employing this requires the element to have Layout, so remember to add zoom: 1; or another appropriate property-value pair that gives Layout.

The full solution

.rotate {-moz-transform: rotate(-5deg);-o-transform: rotate(-5deg);-webkit-transform: rotate(-5deg);transform: rotate(-5deg);-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.9961946980917455,M12=0.08715574274765817, M21=-sizingMethod='auto expand')";filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',M11=0.9961946980917455,M12=0.08715574274765817,M21=-0.08715574274765817,M22=0.9961946980917455);zoom: 1;}
Top tool: WestCiv’s transform style generator ( generates code for modern browsers. gives the code with the IE filter fallback.


10. Transition

The property transition allows for graceful shifts of dynamic element value changes. The syntax for transition is:
<-prefix->transition:<property> <duration><timing-function> <delay>;
  • property: you can name the specific CSS property to which the transition is applied, or you can use the value all. 
  • duration: defines the length of time that the transition will take. 
  • timing-function: describes easing functions – the intermediate values used during a transition – will be calculated. 
  • delay: defines the start of the transition. You can have multiple value sets to one transition property.
Tim Van Damme's homepage
Tim Van Damme's popular site at employs a subtle linear transition upon hovering
While the property is supported in all modern browsers, its rendering is not created equally.
The transitions in Mozilla are still quite choppy despite allegedly being supported, while they’re smooth in Safari and Chrome. As for a filter … well. This is an instance where there are several Internet Explorer filters that could be applicable, but it’s largely dependent upon which transition property you’re employing. Perusing the Internet Explorer filter resources at the Microsoft site is a good starting point.

The full solution

#photos > img:hover {-moz-transform: scale(1.1,1.1);-webkit-transform: scale(1.1,1.1);-o-transform: scale(1.1,1.1);transform: scale(1.1,1.1);-moz-transition: all 1s ease-in-out;-webkit-transition: all 1s ease-in-out;-o-transition: all 1s ease-in-out;transition: all 1s ease-in-out;}

Hopefully this primer has given you the inspiration to get on the bandwagon and start using CSS3 now. Its acceptance and adoption by front-end developers and designers increases in popularity daily, and every new release of the modern browsers shows increased support, even IE9. And if CSS3 is getting you excited, then you should check out some of the great HTML5 features, such as how to add HTML5 video to your site! What are you waiting for?