This page is a draft. If you're just here for the working version, scroll on down.

Author's note. This page has been checked out as ok on Win 98 with Op 5.12 & 6, NS 6.2, and IE 5.5 and 6. Also ok on Linux/Konquerer 2.2 (thanks Nik). Please send notes on rendering by other browsers to brian[at]ecoculture[dot]com.

Thanks to Big John via the Practical CSS discussion list for help fine tuning the text.

What's a link block? I am.

Well, that's not very interesting. Unless you're using the Opera browser, in which case the link looks like:

What's a link block? I am.

Yep. Funny thing, but Opera wants to overline, rather than underline, a link with the style property "display: block." There was a big vote, and the overwhelming opinion is that this is a bug. So, I'm sure Opera will fix it soon. Meanwhile, I've added "text-decoration: none" to the properties for all the examples below. That gets rid of underlines and overlines.

Back to our story. If you've been reading closely (or if you've already peeked under the hood at this page's code), then you know that the essence of a link block is the CSS styling:

a {display: block}

This makes the link behave more like a paragraph than a sentence. But that's not quite the point. To see the point, we've got to add a few other properties. A border makes it easier for us to see what's going on, and a little color will help, too.

Link block with border

Compare that to this link, which is an inline element, the default style for "a" tags. Both links have a 1 pixel border. With the link block, this border shows how the link behaving as a block element extends all the way across the page. All that white space inside the box to the right of the text is part of the link.

Let's make it look a little better. The width property will adjust the link block's size. I like relative units, so I'm using "width: 25%". "Width: 100px" or whatever would work, too. I'm also changing the background color when the mouse moves over the link block. And I'm adding a second link so you can start to visualize a menu. You can see the CSS for this in the page source as "a.test1" and "a.test1:hover".

Link 1 Link 2

Not bad, but those links are kind of cramped all the way over to the left. A little padding should improve things. Let's try "padding-left: 2%".

Link 1 Link 2

There you go. Feel free to stop reading.

Or continue, but it gets a little more complicated. Sometimes it's nice to put all your link blocks in a nice box. For example, we might want to position the link blocks as a single menu. Here I've wrapped the links in a division with a border.

Link 1 Link 2

I need to narrow the menu box to better fit the link blocks, but how wide? Well, the link blocks have a width of 25%, but I can't just make the menu box 25% wide, too, or this will happen:

Link 1 Link 2 longer link

The link blocks are now 25% of the menu box which is 25% the width of the browser window.

Time to discuss differences in CSS implementation among browsers: the NSOp and IE options. For the NSOp option, I set the menu box width at 25% and just delete the width property from the link blocks. The links blocks fill the menu and behave as demonstrated above.

Link 1 Link 2

IE users will find the NSOp path a little bumpy. Only the text acts as a link. You can't click in the space within the menu box to the right of the text. You might also notice that the links move on hover. Big John wondered why the link moves, so he noodled around with the code til he figured that IE just doesn't like the use of % for the padding. Change it to em or px, and the link stays put.

IE likes its blocks with specified widths. If I add "width: 100%" to the link block properties, IE behaves very well.

Link 1 Link 2

But NSOp users may think they're seeing double when they look at the right edge of the menu box. The link blocks poke right out of the side of their container.

Width isn't as wide as I thought it was. The CSS box model shows the total width of a box comprised of margins, borders, padding, and content. But the width property of an element refers only to the width of the content. What? Back to our example.

The width of the active area of the link block (i.e., the text and surrounding background) is 100% of its containing block, which is the menu box. The total width of the link block's box (i.e., the link plus its left and right padding, borders, and margins) is 100% of the width of the menu box plus 2% of left padding plus 2px for the left and right borders.

IE pushes out the right edge of the menu box to account for the padding and borders. This keeps the link block neatly inside its container. NSOp leaves the menu box alone and lets the link block overlap and if necessary run right out of the menu box.

Resolving differences. I remove the padding for the link blocks, and the text bumps into the left border. So, insert   to push it back away. Change the menu box's border color to match the link blocks' borders.

  Link 1   Link 2

We're close, but in NSOp, on hover the background partly overlaps the right border. Actually, it's always overlapping the right border, but most of the time the property "background-color: transparent" is in effect so the underlying menu box's right border shows through. When the cursor is moved over the link block, its background color changes and covers the menu box's right border.

The almost-right % code:

	.menu {width: 25%;
		border: 1px solid #f90} {text-decoration: none;
		color: #03f;
		background-color: transparent;
		width: 100%;
		border: 1px solid #f90;
		display: block} {color: #03f;
		background-color: #ff3}

Pixel perfect. One way to clean this up is to use pixels. Define the width of the menu in pixels; remember this sets the width of the area inside the menu box's padding, border, and margin. I'll use 100px for this example. Then I make sure the total width of the link-block box adds up to 100px. In this example, it's 88px content plus 10px for left padding plus 2px for borders, no margins. I'm dumping the   and going back to padding to keep the link away from the left border.

Link 1 Link 2

NSOp and IE6 all display it as intended. To make this work in IE5, you'll need to apply the box-model hack.

The pixel code:

	.menu {width: 100px;
		border: 1px solid #f90} {text-decoration: none;
		padding-left: 10px;
		color: #03f;
		background-color: transparent;
		width: 88px;
		border: 1px solid #f90;
		display: block} {color: #03f;
		background-color: #ff3}

Gimme some structure. Thus far we've dealt with presentation and mostly ignored structure. Links in a menu are part of a list, often comprised of more than one level. In straight HTML, a menu might be:

Let's use CSS to change the presentation of this structured list and make use of the link blocks. First, we override the browser's default properties for the list type and its elements. Here, we're using an unordered list so we create a menu class and apply it to the <ul> tag; the style properties get inherited by the individual <li> tags.

With "list-style-type: none" we get rid of the symbols in front of each list item. To cover both menu levels we apply the styles to ".menu" (level 1) and to ".menu ul" (level 2, the lists nested within each level 1 list item).

Then we adjust the margins and padding. OpIE set list indentation with margins, and NS indents with padding. In this case, we want both margin and padding set to 0 so that we can adjust them within our link block. We have to set these to 0 for every <ul> and every <li> to cover the behavious of all browsers. Last, we give .menu a width of 150px. (Note: In this example, the links are faked, just to reduce the number of styles needed for the demonstration.)

Now we use real links and create our link blocks. Here we apply the styles from the pixel perfect example, adding 50px to "width" to account for the wider menu box (i.e., the <ul> of class "menu"). We also incorporate the box-model hack so it works on more browsers. We add a border to the level 1 list items to wrap the entire menu. We use &nbsp; to move the category headings away from the left border.

Almost there, but the borders are uneven. An easy fix is to change the border property for the link blocks. The border is currently drawn around the entire block, but if we change the style to "border-top: 1px solid #f90" we get rid of some of the extra lines. Also, we remove the bottom border from the first category.

The code:

	.menu {list-style-type: none;
		margin: 0;
		padding: 0;
		width: 150px}
	.menu ul {list-style-type: none;
		margin: 0;
		padding: 0}
	.menu li, .menu ul li {margin: 0;
		padding: 0}
	.group {border-top: 2px solid #f90;  /* apply to level 1 <li> */
		border-right: 2px solid #f90;
		border-left: 2px solid #f90}
	.lastgroup {border: 2px solid #f90}  /* apply to last level 1 <li> */
	.menu a {text-decoration: none;
		margin: 0;
		padding: 0 0 0 10px;
		border-top: 1px solid #f90;
		display: block;
		width: 150px;
		voice-family: "\"}\"";
		voice-family: inherit;
		width: 136px}
	html>body .menu a {width: 136px}
	.menu a:hover {color: #03f;
		background-color: #ff3}


Created: 2002-03-19. Last modified: 2002-03-30.

Copy any code examples you might need for your personal use. All code is embedded in this HTML file. If you want to incorporate the tutorial into your Web site, please e-mail brian[at]ecoculture[dot]com.