Bulletproof CSS Sliding Doors
I have had to build a few sliding doors navigation menus in the last few weeks. I did a quick research and browsed though a few different implementations. To be perfectly honest, I found none of them satisfactory for various reasons. So I decided to crack the nut myself.
Click on the image below to skip to the demo.
The problems with existing implementations
1. Not fully clickable![]()
Douglas Bowman’s original CSS Sliding doors only has one problem. There are 9 dead pixels to the left of every button. I wanted the entire button to be clickable.
2. Uses empty <span> tags
Although it is perfectly valid to have empty spans, even in XHTML 1.0 Strict, I would rather not take this approach. I would like my markup to make sense to future developers.
3. Causes inconsistencies in IE6![]()
Kailoon’s One Image solution works perfectly. This is perhaps the most compatible solution there is. But there is a slight rendering issue in IE6. There is an extra bit of padding to the left of each button. Off course, it can be fixed easily with a little Conditional CSS but it is not the ideal solution.
Also, kailoon adds a 4px padding to the anchors and then uses -4px margin on the <span> to cover it up. Although this mechanism works well, I am not a big fan of negative margins.
4. Breaks when font-size is increased
The most common with most of these implementation is that they cannot cope with increased font-sizes.
5. Uses li:hover which does not work in older browsers
The :hover pseudo-class is not supported by IE6 and below when applied to anything but an anchor. Hence, Stu Nicholls’ 100% Clickable Sliding Doors does not function as expected on older browsers. Otherwise, I really like his solution.
The Solution
We start with a simple unordered list wrapped in a div. Also, the list items have class names to they can be used in conjunction with body ID to highlight a particular tab.
The Markup
<div id="navigation"> <ul> <li class="home"><a href="#"><span>Homepage</span></a></li> <li class="products"><a href="#"><span>Products &amp;amp; Services</span></a></li> <li class="contact"><a href="#"><span>Contact Us</span></a></li> </ul> </div>
The CSS
First off, I will add some basic styling.
#navigation {
background: url(images/navigation.png) top left repeat-x;
overflow: auto;
display: block;
float: left;
width: 100%;
}
#navigation * {
padding:0;
margin:0;
font-family: Georgia, "Times New Roman", Times, serif;
font-size: 1em;
}
#navigation ul {
display: block;
float: left;
padding: 10px 0 0 0;
}
#navigation ul li {
list-style: none;
float: left;
margin: 0 0 0 5px;
}
What I have done here is:
- Add blue background to the entire navigation. You can ignore most of it since it is meant only for the menu I designed. Keep the overflow: auto for clearing the floating unordered list.
- Resetting everything inside #navigation using the very powerful star (*) selector, so they have no margin and padding and so that they inherit the font properties.
- Remove list-style from list items and make them float left.
The Images
I am using 3 different images. Off course, you can combine the 3 images and use background-position to switch the background colour but I can’t be arsed.



One noticeable thing about the images is that they are quite big, almost 3 times as much as what they need to be. It is so if the font-size is increased or the page zoomed, the buttons will expand and will not seem broken.
The CSS for links
#navigation ul li a {
background: url(images/onlink.png) top right no-repeat;
display: block;
padding: 0 15px 0 0;
color: #e0ebf3;
text-decoration: none
}
#navigation ul li a span {
background: url(images/onlink.png) top left no-repeat;
display: block;
padding: 10px 0 10px 15px;
}
At this point, all the links should look the same. If you inspect the code, you’ll see a 15px padding on the right of the anchor. Also, the image is on the right-hand side so that the rounded corners show up on the right.
The CSS for :hover and selecting current tab
#navigation ul li a:hover {
background: url(images/onhover.png) top right no-repeat;
color: #FFF;
text-decoration: underline
}
#navigation ul li a:hover span {
background: url(images/onhover.png) top left no-repeat;
}
#home #navigation ul li.home a {
background: url(images/onselected.png) top right no-repeat;
color: #6a6a6a;
}
#home #navigation ul li.home a span {
background: url(images/onselected.png) top left no-repeat;
}
The code here is quite self explanatory. The image onhover.png is applied on both the anchor and span for the hover effect.
The #home at the front is the body ID. If the body id is set to home, the list item with class=”home” gets the white background image to make it appear selected.
But what about Transparent Images?
If you are using transparent PNGs for the buttons, you will notice that the images overlap.If your images have shadows, the overlap will cause rather ugly results.
I admit I had been wrong on this matter. I stand corrected after a reader has taken the effort to use my code with transparent images and posted it on his website.
The solutoin is to split the images into 2 sections.

Create slices in Photoshop
In the example above, the anchor has a padding of 15 pixels to the right. So we are creating a 15px slice as saving it as a separate image.
Here is the CSS for the 2-image solution:
#navigation2 ul li a {
background: url(images/onlink2_right.png) top right no-repeat;
display: block;
padding: 0 15px 0 0;
color: #e8e8e8;
text-decoration: none
}
#navigation2 ul li a span {
background: url(images/onlink2_left.png) top left no-repeat;
display: block;
padding: 10px 0 10px 15px;
}
#navigation2 ul li a:hover {
background: url(images/onhover2_right.png) top right no-repeat;
color: #FFF;
text-decoration: underline
}
#navigation2 ul li a:hover span {
background: url(images/onhover2_left.png) top left no-repeat;
}
#home #navigation2 ul li.home a {
background: url(images/onselected2_right.png) top right no-repeat;
color: #6a6a6a;
}
#home #navigation2 ul li.home a span {
background: url(images/onselected2_left.png) top left no-repeat;
}
By splitting the images into left and right, I have eliminated the chance of an overlap. It works on all major browser except IE6 because of the alpha-transparency issue. So I have created alternate PNG-8 versions of the images and added the !important hack to make it work in IE6.
Take this step only if you want to support IE6.
#navigation2 ul li a {
background: url(images/onlink2_right.png) top right no-repeat !important;
background: url(images/onlink2_right_IE6.png) top right no-repeat;
display: block;
padding: 0 15px 0 0;
color: #e8e8e8;
text-decoration: none
}
#navigation2 ul li a span {
background: url(images/onlink2_left.png) top left no-repeat !important;
background: url(images/onlink2_left_IE6.png) top left no-repeat;
display: block;
padding: 10px 0 10px 15px;
}
#navigation2 ul li a:hover {
background: url(images/onhover2_right.png) top right no-repeat !important;
background: url(images/onhover2_right_IE6.png) top right no-repeat;
color: #FFF;
text-decoration: underline
}
#navigation2 ul li a:hover span {
background: url(images/onhover2_left.png) top left no-repeat !important;
background: url(images/onhover2_left_IE6.png) top left no-repeat;
}
#home #navigation2 ul li.home a {
background: url(images/onselected2_right.png) top right no-repeat !important;
background: url(images/onselected2_right_IE6.png) top right no-repeat;
color: #6a6a6a;
}
#home #navigation2 ul li.home a span {
background: url(images/onselected2_left.png) top left no-repeat !important;
background: url(images/onselected2_left_IE6.png) top left no-repeat;
}
Check out the updated demonstation.
Conclusion
In comparison to other methods, it is more functional, semantic and better supported in older browsers. It is also easier to deploy and maintain. Here is the live demo if you would like to see it in action. I have also done an extra theme with orange buttons (similar to Kailoon’s demos).
I hope you found it useful. Bugs, fixes and any feedback is very welcome.
References and Credits
CSS Sliding Doors by Douglas Bowman
CSS Sliding Door using only 1 image by kailoon
100% clickable Sliding Doors by Stu Nicholls
Sliding Doors meets CSS Sprites by FiftyFourEleven
This website is hosted by DreamHost. Get $25 Off with promo code: AZADCREATIVE

















Comments
(30) Skip to comment formKarl
April 3, 2009 at 8:08 am
Demo doesn’t work?!
Azad
April 3, 2009 at 8:39 am
It seems to be working. What problem are you having?
Duca
April 3, 2009 at 11:48 am
Demo doesn’t work.Click on tabs and nothing happend… Firefox 3.0.8
Azad
April 3, 2009 at 12:11 pm
Well, the sliding doors technique simply shows how to make those buttons. What they do and where they point to is upto you.
This is not a tutorial for making interactive tabs. Try a little Jquery to turn them into tabs.
Tommie Hansen
April 4, 2009 at 2:15 pm
Yeah, we’ve all had to do our own sliding doors modifications to get it fully working… It’s a pity. It’s nice of you to share the fluff with the rest of the world though!
I’ll have to compare your stuff with mine as well now…. or… for a new client.
Ian
April 4, 2009 at 3:24 pm
Nice idea, and makes sense for non-transparent images, but this technique won’t work with transparent images, because the ‘a’ and ’span’ overlap.
Azad
April 4, 2009 at 4:26 pm
@tommie: Glad it is coming to some use. By the way, I think your site is stunning.
@Ian: The images do not technically overlap. Read the origanal Sliding Doors article at ALA. I tried this with transparent PNG and it works fine.
Tommie Hansen
April 7, 2009 at 6:04 am
Azad: Thanks!
Keep up this real-world-knowledge posts, it’s nice to see something else besides the more newbie friendly ones found on other more popular sites (smashingmagazine.com, nettuts etc..)
Marek | Webcentric
April 7, 2009 at 2:57 pm
Asalamu alaikum,
Very informative post, very detailed instructions. Looking forward to more.
Forrest
April 30, 2009 at 5:56 pm
I just tried this with transparent PNGs and it does seem the images overlap and thus this method doesn’t work with transparency. (The original ALA method doesn’t either.)
I took your demo page and swapped out the link and hover PNGs for a pair with transparent corners. http://client.giraffedesign.com/test/azadcreative-sliding-doors.html
Note the top left corner is rectangular. I tweaked it a bit so when you hover you can see that the images do indeed overlap. (The top left corner turns yellow.)
Azad
May 3, 2009 at 10:36 am
Thanks Forrest. I have updated the post with a solution to the problem. It does require twice as many images but it is solid and works everywhere.
Jason
May 19, 2009 at 5:47 pm
Unfortunately the demo breaks when the font size is increased. Increasing by one level in Firefox (3.0.10, if it matters) separates the tabs from the white page area below them; increasing by two levels breaks the “Products and Services” image; and so on.
Erick
June 4, 2009 at 1:55 pm
Question. Have you ever tried adding a down effect using :active ?
I tried what is shown on the link below.
It works great but it has a problem on IE8. I know IE8 sucks but I kinda need some help resolving this.
Give it a try on FF and see how it works as it should there. On IE8 it does not respond when you press on it, actually it you press on the right end of the button you’ll notice how it goes down when you press it. The problem seems to be the tag, that’s where IE8 doesn’t want to respond as it should.
http://www.chidissimmo.com/myButton
Thanks in advanced for any help. =)
letscounthedays
June 22, 2009 at 2:14 pm
Great article, thank you for sharing.
I’ve used the sliding doors technique quite a bit in my freelance web design work over the past few years and it is definitely a trick of the trade. Highly recommend to anyone new to web design or CSS.
Jonathan Shroyer
July 14, 2009 at 7:25 pm
Very nicely done. If you want to take it one step further (which I plan on doing soon) is to remove the flicker in IE6. You can do that by loading the hover state under it and doing display:none when hovered over to reveal the hover state. Hopefully it can be done with this method since it’s so clean.
Richard
July 22, 2009 at 9:53 pm
Hello, when I try the code on my WordPress, everything works fine except that the current page is not highlighted. More detail here: http://wordpress.org/support/topic/292830?replies=1#post-1148263
What am I doing wrong?
Brandon
August 16, 2009 at 11:34 am
I cannot seem to get the hover (swapped images) to work.
What happens is that the natural state do not line up with the hover state (in fact the image for the hover state is pushed a ways to the right. (additionally the left side hover image; my special shape corner; does not even become placed.)
Am I suppose to add a Display: block or something to get both the images to align without any issue?
Thanks,
B
Brad
September 30, 2009 at 11:08 am
I just used your sliding door solution with transparent images, and it worked like a charm! Thank you so much for posting this; it honestly made my day.
Adrian von Gegerfelt
February 3, 2010 at 8:06 am
Use Adobe Fireworks to save the PNG-8 images with alpha transparency instead (photoshop can only save with index transparency). Then the semi-transparent pixels will be ignored in IE6.
This way you only need one image that will work on all browsers, just look slightly jaggy in IE6.
william w.
February 24, 2010 at 7:49 pm
This is a GREAT sliding door technique! Awesome job! I do have a problem though, for some reason my “selected” link isn’t selected. Any help would be appreciated!
Thanks!
Tom
March 8, 2010 at 6:13 am
When I attempt to look at the demo, my antivirus says that the page contains a trojan: Downloader.JS.Pegel.k
Please fix.
Thanks
Bulletproof CSS Sliding Doors « AzadCreative | Best Web Gallery
March 26, 2009 at 3:00 am
[...] Bulletproof CSS Sliding Doors « AzadCreative [...]
Bulletproof CSS Sliding Doors : Design Newz
April 2, 2009 at 1:16 am
[...] Bulletproof CSS Sliding Doors [...]
The Rollsteady Network » Blog Archive » links for 2009-04-03
April 3, 2009 at 5:30 pm
[...] Bulletproof CSS Sliding Doors « Azadcreative / Front-end Web Developer (tags: css navigation tabs slidingdoors) [...]
links for 2009-04-04 * RobMaurizi.com
April 4, 2009 at 3:01 am
[...] Bulletproof CSS Sliding Doors « Azadcreative / Front-end Web Developer Very elegant sliding doors solution. This coming from a guy who hates sliding doors! (tags: css buttons tabs code webdesign navigation menu slidingdoors) [...]
Bulletproof CSS Sliding Doors Menus | Feed Reader (Beta)
April 5, 2009 at 10:00 pm
[...] DIRECT LINK » [...]
CSS Sliding Doors 1-Image 100% Clickable | Psychic Squirrel
June 3, 2009 at 1:38 am
[...] technique using 1 image and a fully clickable area. The most recent blog post I’ve found, Bulletproof CSS Sliding Doors, seems to build off all previous iterations. But during construction, I found these blogs more [...]
24 CSS (in some cases with jQuery) Navigation and Menu Tutorials : Speckyboy Design Magazine
June 8, 2009 at 7:14 am
[...] Bulletproof CSS Sliding Doors [...]
75 Amazing CSS Navigations and Jquery Examples | Design Dazzling
August 8, 2009 at 2:56 pm
[...] Bulletproof CSS Sliding Doors [...]
Techflaps | 15 Tutorials on Creating CSS Navigaton Menus with Sliding Doors Effect
August 20, 2009 at 7:30 am
[...] Bulletproof CSS Sliding Doors [...]