Frontend Friday: Implementation focus on Indiscript’s lettered menu

For this week’s Frontend Friday I wanted to get a little more technical, and decided on focusing on and working though the implementation of Indiscript’s menus — the main navigation up top, and the script highlights on the sidebar:

What’s interesting about this implementation is that if I were to rename sections around, add new scripts to the sidebar, and otherwise need “new” menu items, I’ll never need to do anything more than just add the menu/link item, and every menu item or link presented this way makes use of just one 61.5kb image.

When I was working with the Indiscripts revamp, I knew I wanted something relatively simple, light, and easy to implement and extend for if/when I need to add new sections to the website. Usually that meant that artsy menu items were out…but I didn’t want to give up so easily. The result is the menu/link style you see now: an artsy letter serves as a background, usually in plain grey. The active menu item is green, and when you’re hovering over it, it becomes orange. If I wanted to use blue, pink, yellow, brown, etc–that’s all possible, with the help of CSS and PNG.

To make sure I have everything ready for if/when the time comes to add sections, I prepared a sprite image containing all the letters of the alphabet. For the uninitiated, a sprite (in terms of web development/CSS) is an image made up of several smaller images in measured distances from each other, in the interests of reducing HTTP requests and speed up website load times (see Website Performance’s What are CSS sprites?).

Part of my letter sprite looks like this (black background added for clarity):

A couple of notes on this sprite:

  1. The distances between each sprite is carefully calculated, and yes, manually done. That means that if I have a menu item that is too long (say more than 550 pixels wide), the letter next to the sprite shows up. But we’re talking menu items here, anyway, so this isn’t a big issue. I could even go as low as a width of 300 pixels.
  2. If you scrutinize the above sample, the letters are cut off at the top and left of the letters, because this forms the upper left corner of the menu item. There is pretty much no reason to keep the swirls at that portion of the letters, because it will be cut off, and keepting them would add complexity and raise the file size of the sprite. However, it is important to keep the swirls to the right and bottom of the letter, because the menu items will probably expand to the right and/or grow taller depending on the content of the item. Its limitation? I can’t have these artsy letters aligned on the right.
  3. I could have used GIF, but I went with PNG. PNG is well-supported now, except for IE6, but basically PNG here lets me have different, CSS-specified backgrounds for the letter, and have the letter blend cleanly against the solid background. Win!

Once that’s ready, it’s time for the markup. Basically what we’re doing is we need at least two separate “layers” for each menu/link item. One for the colored background (grey, green, and orange); one for the letter on top of this, which should let the colored background show through; and then our actual menu item, if we have multiple-word-set menu items.

Time for some pretty code (with just one, current menu item):

<ul class="menu">
  <a href="" id="menu-blog" class="current">
    <div class="swirl-b">
      <p>tech babble</p>

Now we need to have the menu list items line up horizontally, and we do that with floating things: li {
   list-style-type: none;
   float: left;
   border-right: 3px solid #fff; /* whitespace between each menu item */
   font-size: 85%;
   height: 54px;
   overflow: hidden;

We also need to color the background of an ordinary link to a nice light shade of grey, as well as tacking on additional colors for when we have a currently active menu item, or when hovering over. The current menu item is identified with a current class, but otherwise there shouldn’t be any classes involved. This one forms our background layer. We use the <a> tag so that the whole item is a link, plus we can change the background color across all browsers (IE doesn’t recognize the :hover pseudo-class on anywhere other than <a> tags). li a {
   display: block;
   text-decoration: none;
   background: #e7e7e7;
} li a.current { background: #bddcbd; } li a:hover, li a:active { background: #eed6b4; } li a.current:hover, li a.current:active { background: #bddcbd; }

The next layer is our artsy letter layer, which is the div with a class pertaining to the letter we want to show. First we need set up our actual swirl classes:

.swirl-a, .swirl-b, ... .swirl-x, .swirl-y, .swirl-z { background: url('sprite.png') no-repeat top left; }
.swirl-a { background-position: 0 -30px; }
.swirl-b { background-position: 0 -210px; }
.swirl-x { background-position: -1120px -210px; }
.swirl-y { background-position: -1120px -390px; }
.swirl-z { background-position: -1120px -570px; }

I just showed the classes for the letters A, B, X, Y and Z for simplicity’s sake. I separated the style rule for the common background to minimize code repetition. This can be tricky and a bit tedious, but a nice ol’ calculator can do wonders, if you’ve set up your sprite correctly. After all, the distance of all the sprites are calculated and measured.

Now we have the rest of the styles for our swirl <div>, as well as the <h3> and <p> tags I use for the actual menu text: paddings, font sizes, colors, etc. If I ever need more menu items, or change a menu item’s name, I can just keep adding/changing the markup for that menu item, and everything’s set up for me immediately.

Hope this entry gives inspiration and ideas for more, better implementations. Feel free to ask away if something’s unclear. :)