Using lineheight with menus

Line-height is a property can help us solve menu problems really elegantly. While often we have to battle with paddings, box model, cross browser compliance, using line-height in combination with some other properties can reduce the need for additional markup and additional css definitions. Of course there are cases where this usage that I am about to demonstrate can't be applied, but having this trick under your sleeve can be a good thing when you encounter a perfect situation.

Overview

Let's repeat what line-height is. Line-height property sets the distance between the lines and of course aligns text in the vertical middle of that line.

line-height scheme

It can take values "normal", "inherit", length, numeric and percentage value.

p{
line-height:normal;
}
// numeric
// sets a line height of a number multiplied by current font size
p{
line-height:1;
}
// length
// set fixed line height
p{
line-height:10px;
}
// percentage
// sets a line height in percentages of current font size
p{
line-height:100%;
}

Usage

Being a designer most interesting value that line-height can take is using lengths (fixed heights).
I never use it when defining line height of entire document or any paragraph of text, but I use it when dealing with i.e. single links or menu items. Why? It gives me a chance to be a pixel precise and I like that kind of control a lot! Those of you who wants to keep things fluid and flexible might disagree with me on this, but i.e. if you want your vertical menu on the left to be exactly the same height as your header background image on the right, then you need pixel precision.

Menu with line-height

A really good choice for menus, something that most of use is using unordered list. It gives you 3 elements in hierarchy to work with, plus it structurally and visually separates links, so from accessibility point of view it's all good. Oh yes, semantics. We got that covered too because list if links is - a list :)
So our menu's source looks like this

and for this example that would be all the markup we need... No need for additional spans or anything.

Vertical menu

In this example I will use menu next to an background image. Image has a fixed height of 214px and the goal is to get the menu to be the same height as well. That makes five menu items with 24px in height plus 1px top margins except for the first one (42px x 5) + (1px x 4) = 214 px.
Unstyled, our markup looks like this.

line-height scheme

When we add some styling to it, just to cover the basics. I'll also add a fixed height background image.

ul#nav, ul#nav li{
margin:0;
padding:0;
list-style:none;
}
ul#nav{
background:url(bg.jpg) no-repeat 100% 0;
height:214px;
}
ul#nav li{
width:190px;
margin-top:1px;
}
ul#nav li.first{
margin:0;
}
ul#nav li a{
display:block;
width:100%;
}

it looks like this

line-height scheme

Adding some colors, background images to menu items

ul#nav li a{
display:block;
width:100%;
color:#0e85b0;
background:#bae2f0;
}

will turn our menu into this

line-height scheme

Now, here comes the moment we waited for. What we're aiming at is to set a clickable "button" of a certain height and width with properly aligned text in it. By setting a line height to desired value we get what we want. We'll also use text-indent property to give the text a left offset.
With line-height property we force the menu item to be of a certain (fixed) height and with text-indent we move the text to the left. No paddings to mess with your dimensions.
The css looks like this

ul#nav li a{
display:block;
width:100%;
color:#0e85b0;
background:#bae2f0 url(arrow1.gif) no-repeat 10px 50%;
line-height:42px;
text-indent:25px;
}

and the result

line-height scheme

Take a look at the demo

Pretty simple, isn't it?

Downsides

As I mentioned at the beginning of this article there are a lot of cases that you can't use this approach. In order for this to work as it should, you need your menu items to be one liners. As soon as the text goes into new line the things will not look good. Menu items will be to large and text-indent property works on first line only. I sometimes avoid that to happen with adding this:

 white-space:nowrap;
overflow:hidden;

because I'd sometimes rather risk loosing cou