Inverted Sliding Doors tabs
This is an explanation of how I adapted Doug Bowman’s Sliding Doors technique to work with inverted tabs for a recent redesign of netrelations.se (my colleague Tobias Nilsson did the design). By inverted tabs I mean that they are bottom-aligned, and as text size is increased, more and more of the tabs is revealed from the top down, instead of from the bottom up as in the original Sliding Doors technique.
The tabs being inverted, or upside down, and the dropshadow cast by the header image prevented me from using the original technique without modifying it.
Because the tabs are upside down, with their bottom edges always visible, the background images used to create the tabs need to be positioned at the bottom of the
<a> elements. That makes it impossible (at least I couldn’t think of a way to do it – if you can, please let me know) to put the different tab states (normal, hover, current) in the same image to create single-image rollovers, except for the part of each tab that has a fixed width - in this case the left part. If the width or height of the tabs was known, it would be possible to use full single-image rollovers, but in this case, both will depend on the font size and the amount of text in each tab.
The left part of each tab does have a fixed width, so all images used for that can be merged into a single image. I also put the hover state of the right part in that image, which will preload it to reduce flicker, and reduce the number of server hits by one.
The tabs also have a different look for the current state. Like the normal state, I wasn't able to figure out a way to combine this right part image with any of the others.
The final image used is the header image which, to make things even more complicated, casts a dropshadow on the top edges of the non-current tabs. That makes for a total number of four images used to create the tabs (and the header):
A couple of small adjustments to the Sliding Doors technique are needed to make it work with this design. First of all, there is a one pixel border between the tabs. Since each tab has both a left and a right border, all
<li> elements except the first one are given a left margin of -1px, to make them cover the right border of the previous tab.
Then there’s the dropshadow from the header. To put the tabs, which contain their own version of the shadow, in front of the header,
div#nav is given a top margin of -19px, which equals the distance from the bottom edge of the header image to the start of the dropshadow. The negative margin will pull the tabs in place. And in case you’re wondering why I don’t just use the header image as the background for
div#nav, it’s because of a problem with Safari vertically repeating background images with a negative vertical offset, even when
no-repeat is specified.
To change the state of the tabs, the background image of the left part (which is in the
<li> elements) is shifted horizontally, and the background image for the right part (in the
<a> elements) is replaced with either the hover or current state image.
On netrelations.se, the
<body> element of each page has an id that specifies which tab should be the current one. In the CSS file, a matching rule is then made for each tab. To show what the current state looks like, I’ve specified
id="services" for the
<body> element of this page.
Note that there is no hover effect in Internet Explorer due to its inability to understand the
:hover pseudo-class on anything but links. In this case, I decided to keep the code as clean as possible instead of inserting the extra markup needed to make it work in IE.
In order to avoid the annoying IE/Win flicker that often occurs when you mouse over a link that has a background image and IE’s cache is turned off, I have implemented the fix explained by Dean Edwards in Caching in IE.
The end result looks pretty good to me. It isn’t perfect though. Enlarging the text will make the tabs look less attractive, especially the current tab, but it isn’t a complete disaster.
View source for the CSS and XHTML. If you can think of ways to improve this, please either post a comment to the related blog entry, or use my contact form.