Recently, a reader asked us how we created our floating orange “follow” tab that appears on the right-hand side of every page on elated.com. It’s quite a nice effect and it also uses some interesting new CSS3 features, so I thought it’d make a good topic for a tutorial!
In this tutorial you’ll learn how to:
- Work with CSS sprites
- Position stuff relative to the browser window, rather than the page
- Create CSS3 rounded borders
- Add CSS3 drop shadows, and
- Create cross-browser translucent gradient backgrounds (using no images!)
Ready? Let’s get started!
Step 1. Create the sprite image
Our first job is to create the image for the buttons within the tab. To do this, we’ll use a technique known as CSS sprites. The basic idea is that you create a single image containing all the buttons, in both their normal and their rollover states. Here’s the finished image that we need to make:
You then use the same image as the background for all the buttons, and position the image differently for each button (and rollover state) to reveal just the desired part of the image. It’s almost like sliding the frames of a movie through a movie projector.
My Making CSS Rollover Buttons tutorial uses a simpler version of this technique, creating a rollover effect for a single button.
Using a single sprite image like this gives you a few advantages over having separate images per button and normal/rollover state:
- The resulting single image is usually smaller (in terms of file size) than having separate images.
- The browser only has to request a single image, which results in less network overhead.
- You can group all your button images in a single image file, making them easier to organize.
The disadvantages of sprites include:
- It can be fiddly creating your sprite image, especially if you’re working with elements of different sizes.
- You have to use a tiny bit of maths to work out the background positions for each button.
On the whole, though, using sprites for things like buttons is a good idea, especially if you want the buttons to have a rollover effect.
OK, let’s create the above image! For the elated.com design, Simon (our lovely designer) had already provided me with a Photoshop file containing the tab and basic buttons (you will of course need to create your own design to match the look of your site):
We’ll be creating the tab itself using pure CSS, so the only images we need to deal with are the buttons. Here are the steps to create the sprite image for the buttons:
- Create a new Photoshop document
Make it as wide as the buttons — 24 pixels in the case of elated.com — and reasonably tall, say 200 pixels. Turn off the Background layer so that the document is transparent. Save the file asfollow-tab-buttons.psd
. - Drag the first icon into the top of the document
Select the topmost button image you’ve created — the email icon in this case — and drag it into the document so it sits at the top of the image. - Create a copy of the icon and position it
Drag the icon layer down to the New Layer icon in the Layers panel to copy it. Then use the Move tool with the Up/Down cursor keys to move this layer down so it’s directly below the first layer in the image. You might be able to do this by eye; alternatively, you can use the Rectangular Marquee tool and Info panel to work out the dimensions of the first layer, which will help you position the copied layer. Photoshop’s Guides feature can also help here, as can zooming in! - Create a Brightness/Contrast layer between the 2 layers
Click the copied layer in the Layers panel, then choose Layer > New Adjustment Layer > Brightness/Contrast. Set the Brightness to +50, and leave the Contrast at zero. You should now see that the copied icon is brighter than the original:After creating the Brightness/Contrast layer, the bottom icon is brighter than the top - Group the layers
Now select the 2 icon layers and the Brightness/Contrast layer in the Layers panel, and hit Control/Command-G to group them together. Name the group after the icon (e.g. “Newsletter”), and change its blend mode from “Pass Through” to “Normal” so that the Brightness/Contrast layer doesn’t affect other groups. - Create the remaining icons
You’ve now created your newsletter icon in both normal and rollover states. Now repeat the above process to create the other 3 icons. Again, you can use Guides and other tools to help position each pair of icons in the document. - Trim the image
When you’re done, you’ll probably be left with some vertical whitespace below the last button, so choose Image > Trim and select Transparent Pixels to remove the whitespace.
When you’re finished, you should have a PSD with all of your buttons in both normal and hover states, all nicely aligned vertically and with no gaps:
Save the file, and then use File > Save for Web & Devices to export the sprite as a PNG-24 image. Make sure the Transparency option is selected, since we want our buttons to sit on top of the gradient background. Call the file follow-tab-buttons.png
and save it to an images
folder on your hard drive.
You’ll find the finished PSD inside the images
folder in the code download zip file.
Step 2. Create the basic markup
Our Photoshop work is done. Now we can start creating the tab in our webpage!
First we’ll create a dummy page to hold our tab. For this I’ve simply borrowed the HTML page I created in Smooth Fading Image Captions with Pure CSS3, and stripped out all the things that we don’t need for this tutorial. This page contains an excerpt from a public domain book, along with a few images. I’ve also included some CSS to style the page and the excerpt.
Here’s the page markup:
<!doctype html> <html lang="en"> <head> <title>CSS3 Floating Follow Tab with Rollover Effects | Demo | Elated.com</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <style type="text/css"> /* Add some margin to the page and set a default font and colour */ body { margin: 30px; font-family: "Georgia", serif; line-height: 1.8em; color: #333; } /* Set the content dimensions */ #content { width: 800px; padding: 50px; margin: 0 auto; display: block; font-size: 1.2em; } #content h2 { line-height: 1.5em; } /* Style the images */ img.inline { position: relative; display: block; border: 1px solid #333; margin: 5px 0 10px 0; } /* Header/footer boxes */ .wideBox { clear: both; text-align: center; margin: 70px; padding: 10px; background: #ebedf2; border: 1px solid #333; } .wideBox h1 { font-weight: bold; margin: 20px; color: #666; font-size: 1.5em; } </style> </head> <body> <div class="wideBox"> <h1>CSS3 Floating Follow Tab with Rollover Effects</h1> </div> <div id="content"> <h1>Aircraft and Submarines</h1> <h2>The Story of the Invention, Development, and Present-Day Uses of War's Newest Weapons</h2> <h3>By Willis J. Abbot</h3> <h4>Preface</h4> <img class="inline" style="width: 300px; height: 373px; float: left; margin-right: 20px;" src="images/fighting-by-sea-and-sky.jpg" alt="Fighting by Sea and Sky" /> <p>Not since gunpowder was first employed in warfare has so revolutionary a contribution to the science of slaughtering men been made as by the perfection of aircraft and submarines. The former have had their first employment in this world-wide war of the nations. The latter, though in the experimental stage as far back as the American Revolution, have in this bitter contest been for the first time brought to so practical a stage of development as to exert a really appreciable influence on the outcome of the struggle.</p> <p>Comparatively few people appreciate how the thought of navigating the air's dizziest heights and the sea's gloomiest depths has obsessed the minds of inventors. From the earliest days of history men have grappled with the problem, yet it is only within two hundred years for aircraft and one hundred for submarines that any really intelligent start has been made upon its solution. The men who really gave practical effect to the vague theories which others set up—in aircraft the Wrights, Santos-Dumont, and Count Zeppelin; in submarines Lake and Holland—are either still living, or have died so recently that their memory is still fresh in the minds of all.</p> <p>In this book the author has sketched swiftly the slow stages by which in each of these fields of activity success has been attained. He has collated from the immense (p. iv) mass of records of the activities of both submarines and aircraft enough interesting data to show the degree of perfection and practicability to which both have been brought. And he has outlined so far as possible from existing conditions the possibilities of future usefulness in fields other than those of war of these new devices.</p> <img class="inline" style="width: 452px; height: 300px; float: right; margin-left: 20px;" src="images/a-battle-in-mid-air.jpg" alt="A Battle in Mid-air" /> <p>The most serious difficulty encountered in dealing with the present state and future development of aircraft is the rapidity with which that development proceeds. Before a Congressional Committee last January an official testified that grave delay in the manufacture of airplanes for the army had been caused by the fact that types adopted a scant three months before had become obsolete, because of experience on the European battlefields, and later inventions before the first machines could be completed. There may be exaggeration in the statement but it is largely true. Neither the machines nor the tactics employed at the beginning of the war were in use in its fourth year. The course of this evolution, with its reasons, are described in this volume.</p> <p>Opportunities for the peaceful use of airplanes are beginning to suggest themselves daily. After the main body of this book was in type the Postmaster-General of the United States called for bids for an aërial mail service between New York and Washington—an act urged upon the Government in this volume. That service contemplates a swift carriage of first-class mail at an enhanced price—the tentative schedule being three hours, and a postage fee of twenty-five cents an ounce. There can be no doubt of the success of the service, its value to the public, and its possibilities of revenue to the post-office. Once its usefulness is established it will be extended to routes of similar length, such as New York (p. v) and Boston, New York and Buffalo, or New York and Pittsburgh. The mind suggests no limit to the extension of aërial service, both postal and passenger, in the years of industrial activity that shall follow the war.</p> <img class="inline" style="width: 420px; height: 321px; float: left; margin-right: 20px;" src="images/the-giant-and-the-pigmies.jpg" alt="The Giant and the Pigmies" /> <p>In the preparation of this book the author has made use of many records of personal experiences of those who have dared the air's high altitudes and the sea's stilly depths. For permission to use certain of these he wishes to express his thanks to the Century Co., for extracts from <i>My Airships</i> by Santos-Dumont; to Doubleday, Page & Co., for extracts from <i>Flying for France</i>, by James R. McConnell; to Charles Scribner's Sons, for material drawn from <i>With the French Flying Corps</i>, by Carroll Dana Winslow; to <i>Collier's Weekly</i>, for certain extracts from interviews with Wilbur Wright; to <i>McClure's Magazine</i>, for the account of Mr. Ray Stannard Baker's trip in a Lake submarine; to Hearst's International Library, and to the <i>Scientific American</i>, for the use of several illustrations.</p> </div> </body> </html>
Save this page as index.html
in the same place as your images
folder you created earlier.
I’ve included the images from the page in the code download (click the button at the top of this article). Put these images in your images
folder.
Step 3. Add the markup for the tab
Now that we’ve built our holding page, we can begin to add the tab itself.
First, the tab’s markup:
<ul id="followTab"> <li><a class="newsletter" href="/newsletter/" title="Subscribe to the Elated Extra newsletter"><span>Subscribe to the Elated Extra newsletter</span></a></li> <li><a class="rss" href="http://feeds.elated.com/ElatedNewStuff" title="Subscribe to Elated.com's RSS feed"><span>Subscribe to Elated.com's RSS feed</span></a></li> <li><a class="twitter" href="http://twitter.com/ElatedDotCom" title="Follow Elated.com on Twitter"><span>Follow Elated.com on Twitter</span></a></li> <li><a class="facebook" href="http://www.facebook.com/ElatedDotCom" title="Follow Elated.com on Facebook"><span>Follow Elated.com on Facebook</span></a></li> </ul>
As you can see, our tab is just an unordered list of links. We place each link’s text in a span
element so that we can hide the text for CSS-enabled browsers (and display the button instead).
We’ve given the list an ID of followTab
so that we can style it as our floating tab. Each link is given its own class (newsletter
, rss
, twitter
, facebook
) so that we can style each link with its own button image. Simple!
Place this markup into the page you created in Step 2. I placed it just before the "content"
div
, but in fact you can place it pretty much anywhere you like inside the body
element, since it will be floated above the rest of the page content.
Step 4. Style the tab
Now comes the fun bit! It’s time to style our #followTab
ul
element so that it looks like a tab.
Here’s the CSS:
/* The tab itself */ #followTab { /* No bullets */ list-style: none; /* Position and float the tab */ position: fixed; z-index: 1; right: 0; top: 130px; /* Give the tab width and padding */ width: 24px; padding: 8px 5px; /* Add the curved white border */ border: 3px solid #fff; border-right: none; -moz-border-radius: 10px 0 0 10px; -webkit-border-radius: 10px 0 0 10px; border-radius: 10px 0 0 10px; /* Add the drop shadow */ -moz-box-shadow: 0 0 7px rgba(0, 0, 0, .6); -webkit-box-shadow: 0 0 7px rgba(0, 0, 0, .6); box-shadow: 0 0 7px rgba(0, 0, 0, .6); /* Add the semitransparent gradient background */ background: rgba(239, 91, 10, .75); background: -moz-linear-gradient(top, rgba(243, 52, 8, .75), rgba(239, 91, 10, .75)); background: -webkit-gradient( linear, left top, left bottom, from( rgba(243, 52, 8, .75) ), to( rgba(239, 91, 10, .75) ) ); background: linear-gradient(top, rgba(243, 52, 8, .75), rgba(239, 91, 10, .75)); filter: progid:DXImageTransform.Microsoft.Gradient( startColorStr='#c0f33408', endColorStr='#c0ef5b0a', GradientType=0 ); }
Let’s work through each section of the above CSS:
- No bullets
By default, list items have bullets to the left of them. We don’t want the bullets, so we turn them off usinglist-style: none
. - Position and float the tab
The trick to keeping the tab locked to the browser window instead of the page is to useposition: fixed
. This behaves much likeposition: absolute
in that the element is taken out of the page flow, and you can then position it precisely using thetop
,right
,bottom
andleft
properties. However, whereasposition: absolute
is relative to the document,position: fixed
is relative to the browser window. (Read more about positioning elements using CSS.)We also give the element az-index
of1
to ensure it floats above all other content in the page (you might need to use a higherz-index
if you’re already usingz-index
in your page), then we useright
andtop
to position the element on the right-hand edge of the browser window, 130 pixels from the top. - Give the tab width and padding
Next we use thewidth
andpadding
properties to make the tab 24 pixels wide with 8 pixels of padding top and bottom, and 5 pixels of padding left and right. This ensures our icons will fit snugly within the tab, with a nice even amount of space around them. - Add the curved white border
We use theborder
property to add a 3-pixel white border to the tab. Since we don’t want a border on the right, we also useborder-right: none
to override the right border.We then use the CSS3border-radius
property to add 2 curves to the border: one on the top left, and one on the bottom left. By passing 4 values toborder-radius
, we can specify the curve radius on each individual corner of the border. The 4 values work clockwise from the top left corner. Soborder-radius: 10px 0 0 10px
adds 10-pixel curves only to the top left and bottom left corners.As well as the standard
border-radius
property, we add vendor-specific properties for Mozilla and WebKit browsers. - Add the drop shadow
We use the CSS3box-shadow
property (along with the vendor-specific versions) to add a subtle drop shadow to the tab, enhancing its “floating” effect. We set the drop shadow directly below the tab by specifying zero for both the horizontal and vertical offsets, and give the shadow a blur radius of 7 pixels. For the shadow colour, we use black with 60% opacity, so that the page content shows through the shadow slightly. - Add the semitransparent gradient background
The last — and most complex — step is to add the gradient background to the tab:-
- First we use the
background
property to specify a single-colour background for browsers that don’t support CSS3 gradients. By specifying the colour inrgba
format, we can set the background to 75% opacity, thereby making it translucent so that the page content can show through underneath. - Next we add a gradient background using the Mozilla gradient format,
-moz-linear-gradient
. We start the gradient at the top of the tab (it then defaults to ending at the bottom), and create 2 colour stops for the gradient — one at the start of the gradient, and one at the end. We specify both colours inrgba
format with an opacity of 75%, making the gradient translucent. - We then specify the same gradient in WebKit format. WebKit’s gradient format is both more flexible and more complex than Mozilla’s. First we specify a linear gradient (as opposed to radial). Then we specify that we want the gradient to run from the top left corner of the tab to the bottom left corner. Finally we specify the 2 colour stops using
from
andto
, again specifying the colours inrgba
format so we can set an opacity of 75%. - Lastly, we add the gradient for IE browsers. IE does things a bit differently, using its proprietary
Gradient
filter to specify the gradient. We set the start colour for the gradient usingstartColorStr
, the end colour usingendColorStr
, and a vertical (top-to-bottom) gradient withGradientType=0
. The colours are specified in hexadecimal#AARRGGBB
format, whereAA
is the alpha (opacity) value. In this case we’ve used#c0
, which is equivalent to 75% opacity.
- First we use the
Update 11 April 2011: Sadly, although IE9 at last supports
border-radius
(hurrah!), it has a problem when using itsGradient
filter in combination withborder-radius
: the background bleeds outside the rounded corners. Ah well — I thought IE9 sounded too good to be true. 😉There are a couple of workarounds, as documented in the above link: You can use an SVG gradient (pretty painful) or just revert to using a gradient background image for IE9. This is what I ended up doing on www.elated.com — I created a 10×122-pixel gradient image in Photoshop based on the 2 RGB colour stops in the CSS, then set its layer opacity to 75% and exported as a PNG-24 image with transparency enabled. I removed the
Gradient
filter entirely from the CSS, and now just serve the background image to all versions of IE. It’s a shame that we have to fall back to images for a browser as new as IE9, but there you go.Here a handy comparison of Mozilla’s and WebKit’s gradient formats, and here’s an explanation of IE’s
Gradient
filter. -
Step 5. Style the list items and buttons
With our tab styled, it’s time to move onto the buttons within the tabs. First we’ll apply some general styles both to the list items, and to the links (i.e. the buttons) inside the items:
/* Items within the tab */ #followTab li { margin: 9px 0 0 0; line-height: 0; } #followTab li:first-child { margin-top: 0; } /* General style for buttons within the tab */ #followTab a { display: block; width: 24px; background-image: url("images/follow-tab-buttons.png"); } #followTab a span { position: absolute; top: -999em; }
As you can see, we’ve applied various margin
and line-height
values to each li
element within the list, in order to space the elements out nicely across all browsers.
For the links/buttons, we’ve used display: block
so that we can control the width and height of the links, and specified a uniform width of 24 pixels (the width of the buttons). We’ve also added our sprite image from Step 1 as the background image for each of the buttons.
Finally, we hide the span
elements within the links so that the link text doesn’t display and mess up the buttons. We do this by setting position: absolute
on the span
s, then moving them way above the top of the browser window using top: -999em
.
Why not just hide the span
elements using display: none
? The main reason is that we want screen readers to read out the link text. Most screen readers won’t announce text that is hidden with display: none
.
Step 6. Style each button within the tab
As well as applying the above generic styles for the buttons, we also need to style each button individually, since each button is different! Here’s the CSS:
/* "Newsletter" button */ #followTab a.newsletter { height: 16px; background-position: 0 0; } #followTab a.newsletter:hover { background-position: 0 -16px; } /* "RSS" button */ #followTab a.rss { height: 24px; background-position: 0 -32px; } #followTab a.rss:hover { background-position: 0 -56px; } /* "Twitter" button */ #followTab a.twitter { height: 15px; background-position: 0 -80px; } #followTab a.twitter:hover { background-position: 0 -95px; } /* "Facebook" button */ #followTab a.facebook { height: 24px; background-position: 0 -110px; } #followTab a.facebook:hover { background-position: 0 -134px; }
For each button, we’ve specified the button’s height, and also adjusted the position of the background sprite image so that the appropriate button image appears for that button. For example, with the “RSS” button we’ve moved the background up 32 pixels, since that’s where the top of the RSS button image sits within the sprite.
In addition, we’ve given each button a rollover state with the :hover
pseudo-class. Again, this involves sliding the background image up a number of pixels so that the appropriate rollover button image is displayed.
As you can see, it’s a bit of an effort working out the offsets for each button, but it doesn’t take too long. You can also use Photoshop to help you by adding guides to the PSD, as I’ve done in the example. You can then use the values in the Info palette to read the offsets.
Step 7. Add a band-aid for IE6
Poor old IE6. It’s getting so long in the tooth now, and yet many people still have (want?) to use it! Its CSS support leaves a lot to be desired, and it doesn’t even support position: fixed
, bless it.
Now, there are a few hacks around to emulate position: fixed
in IE6. Personally I don’t care enough about IE6 to bother, so I was happy to have it just putting the tab in the right place in the page, but scrolling with the content. To do this, we just need to add a conditional comment for IE6, where we change #followTab
from position: fixed
to position: absolute
:
<!--[if lt IE 7]> <style type="text/css"> /* Band-aid for IE6 */ #followTab { position: absolute; } </style> <![endif]-->
It’s also worth pointing out that some features, such as the curved corners and drop shadow, won’t work in IE7/8 (since they don’t support them). I don’t currently have IE9 to test with, but they should work in IE9 (can anyone confirm?).
The finished product
And we’re done! Again, here’s the finished demo of our floating, curvy, translucent tab with lovely gradient background and drop shadow. Try narrowing your browser window to see how the tab sits over the page content. And, of course, you’re probably looking at the live version on elated.com right now too! 🙂
I hope you enjoyed this tutorial. Let me know what you think in the comments below. Thanks!
mguerra79 says
Niiiice… I need to start learning this stuff!
Thank you for this post!
Cheers from Portugal!
Márcio Guerra
matt says
Thanks Márcio. 🙂 I hope you found the article helpful!
mguerra79 says
Of course I did. The question is «when do I get some discipline to start learning this properly»?
I don’t know what I do to my time, and the time I should be spending learning, whatever, I’m not doing it. However, thanks to the power of the web, I can always get back to this kind of tutorials (yours are really good, specially in the «web department») and do it whenever I want to…
So, thank you, and believe me, it is very helpful!
Cheers from Portugal and Merry Xmas to you all!
Márcio Guerra
psolomon says
Greetings Matt,
How do I change the color of the tab itself? The two color values most apparent to me were in these lines of code…
…and I changed both values, but to no avail.
Philip
matt says
@psolomon: That’s the right chunk of code, but you need to change all the colour values. The first line is the fallback background colour if the browser doesn’t support gradients, while the remaining lines all specify gradients with start and end colour stops.
webgodjj says
I think it would be best to not use display:none for the spans. Instead: positions: absolute; left: -2000px;
Reason: Display none is not supported by most accessible screen readers. And though not an issue now, possibly search engines might start banning display:none from results.
matt says
@webgodjj: Good call – that’s a bad habit of mine! I’ve now changed it in the article, demo, code download, and http://www.elated.com – phew 🙂
Sueli says
Thank you. I had been looking all over for a tutorial on how to do these floating tabs!
matt says
@Sueli: You’re welcome – glad you found what you were looking for 🙂
incrowdsource says
Very nice and easy copy&paste script, I’ve created a variation of the script with a dark background, left aligned and with free-for-commercial purposes icons, here’s the code:
HTML
CSS Style:
The 3D box icons can be downloaded from here and uploaded to /images/ folder: http://www.incrowdsource.com/files/social_sticky.zip
You can see this version of the script in action @ http://www.incrowdsource.com/index.php
matt says
@incrowdsource: Thanks for posting your variation!
Susana says
You certainly made my day! Thank you it’s a really smart piece of code that you made here, simple and works like a charm.
Matt Doyle says
You’re welcome Susana! Glad it helped 🙂