
Dancing with a tambourine for blondes, or about tabbed menus and cunning work with graphics
Actually, not so long ago a small customer passed me. It seems to be simple - but I had to dance a little with a tambourine. And all due to the fact that the customer turned out to be a little “avid for design blonde” (figuratively speaking), and demanded strict conformity of the final result with the layout. He demanded pixel by pixel, and he was completely not worried about issues such as validity, semantics, and all that. “Make up the tables, but make them.” And today we will talk about how in such conditions to make a very tricky drawn menu with tabs. As well as for your code not to be ashamed, and not to fall into the dirt face in front of the customer, that is the question?
Actually, here is a fragment of the sketch responsible for the very menu:

But here is how it should look when another item is selected:

Inconvenient, right? Not only will it not be possible to create a single background for menu items (because of this unfortunate gradient and not only), but you will have to assign styles to each item individually (I had to take an honest pioneer word from the customer that the menu structure will remain unchanged in the future), so and you have to think about how to correctly display the "overlap" on other items before and after the active. But nothing is impossible, and for the implementation of such a thing, we do not need any tables, and there will be a minimum of “crutches”. The whole point is in cunning work with graphics.
But before styling the menu, we need to take care of the block under it. We give it a single-pixel border (the one that we see under inactive items) and a background in the form of a “corner” in the upper left corner. We will not think about how to display this “corner” in the menu itself - let it lie and don’t ask for food in the block under it, and if necessary, we will simply close it.
Now for each menu item we have to cut two pictures - respectively, inactive and active menu item. And for all menu items except the first, we must also provide for the option "inactive after active", which has no bottom edge on the left. Actually, here is the first menu item in an inactive form:

But here it is, but active:

Please note - the backing for the active item is a little higher in height - we need this just to close the "corner" below.
With other points, everything is a little more complicated. Let's analyze the example of the second menu item. An inactive item is made according to the same principle as the first one:

“Inactive-after-active” differs from it only in the absence of a lower border on the left:

And for the active menu item, we must provide for “overwhelming” on the left, slightly “chopping off” from the previous item:

Now, having cut the graphics, we are taken for the code. Given that this menu is ultimately implemented on Drupal using the menu-attributes module (or whatever), and accordingly, it imposes its own specifics, we will not style the li tag, but the links embedded in it. The HTML code itself, minus the CMS garbage, is like this:
As you can see, almost nothing is superfluous, and semantics are not violated. All the "glamor" and "little thing" we will do in CSS. We will have two style files - for normal browsers and for IE donkey (I hope I do not need to teach you how to connect this file through conditional comments). I’ll say right away that by “donkey IE” I mean the seventh version - because, due to the mass distribution of Vista and the third service pack under WinXP, the sixth is already losing ground ... so screw this nightmare. :) In any case, even in the sixth “donkey” the layout will not go, and unless implemented in the “inactive-after-active” selectors, the menu will not work from the functional menu. So do not care. Go!
First, let's figure out the positioning and height of the block itself. The gaze has probably already noticed - you need to whip the lower image border and the upper block border under the menu. And for this, we will slightly tighten the bottom block, along the way (senks for bug reports in the comments) by moving the links 1 pixel to the left: Immediately - correcting all this kitchen in the table for IE (because there are some nuances of display) Now we prescribe the backgrounds and sizes for active and inactive menu items. The algorithm is as follows: for the first item, increase the height if the item is active (close the corner). Other items, if active, move 6 pixels to the left (remember about overlays). Well and now - we use the magic of CSS selectors in order to change the picture to the inactive menu item that comes after the active one:
And now, there is already a screenshot from a real page in the browser:

Actually, that's all. And this with minimal changes can be extrapolated to any similar task. The main thing is to remember the algorithm.And if it’s interesting, I’ll tell you in the corresponding blog about how to correctly and logically implement all this on the Drupal internal structure. Since it’s interesting, here’s how it is implemented on Drupal: habrahabr.ru/blogs/drupal/52601 ;)
Actually, here is a fragment of the sketch responsible for the very menu:

But here is how it should look when another item is selected:

Inconvenient, right? Not only will it not be possible to create a single background for menu items (because of this unfortunate gradient and not only), but you will have to assign styles to each item individually (I had to take an honest pioneer word from the customer that the menu structure will remain unchanged in the future), so and you have to think about how to correctly display the "overlap" on other items before and after the active. But nothing is impossible, and for the implementation of such a thing, we do not need any tables, and there will be a minimum of “crutches”. The whole point is in cunning work with graphics.
But before styling the menu, we need to take care of the block under it. We give it a single-pixel border (the one that we see under inactive items) and a background in the form of a “corner” in the upper left corner. We will not think about how to display this “corner” in the menu itself - let it lie and don’t ask for food in the block under it, and if necessary, we will simply close it.
Now for each menu item we have to cut two pictures - respectively, inactive and active menu item. And for all menu items except the first, we must also provide for the option "inactive after active", which has no bottom edge on the left. Actually, here is the first menu item in an inactive form:

But here it is, but active:

Please note - the backing for the active item is a little higher in height - we need this just to close the "corner" below.
With other points, everything is a little more complicated. Let's analyze the example of the second menu item. An inactive item is made according to the same principle as the first one:

“Inactive-after-active” differs from it only in the absence of a lower border on the left:

And for the active menu item, we must provide for “overwhelming” on the left, slightly “chopping off” from the previous item:

Now, having cut the graphics, we are taken for the code. Given that this menu is ultimately implemented on Drupal using the menu-attributes module (or whatever), and accordingly, it imposes its own specifics, we will not style the li tag, but the links embedded in it. The HTML code itself, minus the CMS garbage, is like this:
As you can see, almost nothing is superfluous, and semantics are not violated. All the "glamor" and "little thing" we will do in CSS. We will have two style files - for normal browsers and for IE donkey (I hope I do not need to teach you how to connect this file through conditional comments). I’ll say right away that by “donkey IE” I mean the seventh version - because, due to the mass distribution of Vista and the third service pack under WinXP, the sixth is already losing ground ... so screw this nightmare. :) In any case, even in the sixth “donkey” the layout will not go, and unless implemented in the “inactive-after-active” selectors, the menu will not work from the functional menu. So do not care. Go!
First, let's figure out the positioning and height of the block itself. The gaze has probably already noticed - you need to whip the lower image border and the upper block border under the menu. And for this, we will slightly tighten the bottom block, along the way (senks for bug reports in the comments) by moving the links 1 pixel to the left: Immediately - correcting all this kitchen in the table for IE (because there are some nuances of display) Now we prescribe the backgrounds and sizes for active and inactive menu items. The algorithm is as follows: for the first item, increase the height if the item is active (close the corner). Other items, if active, move 6 pixels to the left (remember about overlays). Well and now - we use the magic of CSS selectors in order to change the picture to the inactive menu item that comes after the active one:
div#topnav ul.menu {
list-style-type: none;
margin: 0 0 -1px 0;
line-height: 44px;
font-size: 0; /* это чтобы переводы строки между пунктами не отображались как пробелы */
padding-left:1px
}
div#topnav ul.menu li {
display: inline;
}
div#topnav ul.menu a {
font-size: 14px;
padding: 15px 24px 15px 15px;
height: 25px;
margin-left:-1px;
}
div#topnav ul.menu {
position: relative;
top: 3px;
list-style-type: none;
margin: 0px;
line-height: 44px;
font-size: 0;
padding-left: 1px;
}
div#topnav ul.menu li {
display: inline;
}
div#topnav ul.menu a {
font-size: 14px;
margin: 0 0 0 -1px;
padding: 15px 24px 15px 15px;
height: 25px;
}
div#topnav ul.menu li a#apartments {
width: 80px;
background: url('images/menu-1-inactive.gif') top left no-repeat;
}
div#topnav ul.menu li a#houses {
width: 94px;
background: url('images/menu-2-inactive.gif') top left no-repeat;
padding-right:26px;
}
div#topnav ul.menu li a#ground {
width: 150px;
background: url('images/menu-3-inactive.gif') top left no-repeat;
padding-right:26px;
}
div#topnav ul.menu li a#business {
width: 240px;
padding: 15px 60px 15px 15px;
background: url('images/menu-4-inactive.gif') top left no-repeat;
}
div#topnav ul.menu li.active-trail a#apartments {
background: url('images/menu-1-active.gif') top left no-repeat;
padding-bottom: 25px;
}
div#topnav ul.menu li.active-trail a#houses {
width: 101px;
margin-left: -6px;
padding-left: 22px;
background: url('images/menu-2-active.gif') top left no-repeat;
}
div#topnav ul.menu li.active-trail a#ground{
width: 157px;
margin-left: -6px;
padding-left: 22px;
background: url('images/menu-3-active.gif') top left no-repeat;
}
div#topnav ul.menu li.active-trail a#business {
width: 247px;
margin-left: -6px;
padding-left: 22px;
background: url('images/menu-4-active.gif') top left no-repeat;
}
/* this is not supported in IE 6, so screw IE6, we want some CSS2 beauty*/
div#topnav ul.menu li.active-trail+li>a#houses{
background: url('images/menu-2-inactive-after-active.gif') top left no-repeat;
}
div#topnav ul.menu li.active-trail+li>a#ground{
background: url('images/menu-3-inactive-after-active.gif') top left no-repeat;
}
div#topnav ul.menu li.active-trail+li>a#business{
background: url('images/menu-4-inactive-after-active.gif') top left no-repeat;
}
And now, there is already a screenshot from a real page in the browser:

Actually, that's all. And this with minimal changes can be extrapolated to any similar task. The main thing is to remember the algorithm.