Imagine that you are designing a web application interface for an application with multiple areas of functionality. Now imagine that in order to access these areas you will need to have a horizontally aligned, navigation menu running across the top of the screen (not an uncommon sight). Now imagine that this navigation menu will be sitting in liquid layout and will be viewed at various widths dictated by the end user’s browser window size and screen resolution.
So far so good?
Here’s what is could look like.
This is a widely used design and can be achieved with minimal HTML and CSS with no problem, using CSS like this (based on Russ Weakley’s Rollover Horizontal list at Listamatic):
#navContainer ul {
margin: 0;
padding: 0;
list-style: none;
}
#navContainer li {
display: inline;
list-style-type: none;
}
#navContainer a { padding: 3px 10px; }
#navContainer a:link, #navContainer a:visited {
color: #fff;
background-color: #933;
text-decoration: none;
border: 1px solid red;
}
#navContainer a:hover {
color: #fff;
background-color: #369;
text-decoration: none;
}
Splinter and overlap
However there is a common problem that affects most implementations of this type when used in a liquid layout: when the width of the menu’s container is too narrow, the last list items will wrap under the first. This wrapping results in two visual effects that we don’t want;
- If the wrapping list item has a space in its text (eg; “Contact Us”) it will potentially splinter and wrap only the “Us” bit, leaving the menu item reading Contact on one line and Us on the second.
- If the list item and its background color / image is too tall it will overlap the start of the menu making it appear as if the menu items are stacked, obscuring not only the text of the first items, but also the user’s ability to click on them.
Both of these issues can be seen in the following diagram:
![]()
and in this example page showing horizontal navigation (resize your window to see the effect).
CSS to the rescue
Luckily there are two simple CSS solutions to these problems.
- To solve the splintering problem add the rule:
white-space: nowrap;to the list item rules (in my case#navContainer li). This will force the item to wrap in its entirety even if it contains spaces. - To solve the overlap problem set the
line-heightvalue for the list items (again, in my case#navContainer li) to be higher than the text height (remembering the line-height values don’t need a unit,1.2is right,1.2pxis wrong).
Setting these two values on our previous example results in the following:
See an example of the fixed horizontal navigation (again, resize your window to see the effect).
This article was published within the following categories: Interface Design
Comments (10)
Pretty cool. I wasn’t familiar with the whitespace property before now.
I’m not real familiar with liquid layouts as I find fixed a little easier to deal with, but would setting a min-width solve the problem too? I’m not sure if min-width works well across browsers or not as I’ve not dealt with those types of layouts much.
Unfortunately IE doesn’t support min-width so it’s little help from that point of view.
However getting round IE’s lack of support is simple enough; IE treats “width” as “min-width”.
The problem would be that by adding a min-width to the navigation’s container element it will no longer be a true liquid layout; it would scale up as the viewing area gets bigger, but will not scale down to fit in narrower displays leaving some users with the need to scroll horizontally.
I hope that makes sense.
In terms of liquid layouts, I try to use them where
ever possible (personal preference) but they can be a nightmare to get right sometimes.
Well that’s true too. I was thinking more along the lines of setting the min-width on the wrapper/container element and not the navigation container, but I guess either way you’re taking part of the liquidity functionality out of the site.
My main thing with liquid layouts is images. I’m obsessive compulsive sometimes on the placement of things and I like things to be almost perfect. I know if I’m using images inside of sidebar for example and my image is 100px wide on my monitor and looks fine in the sidebar but the next person’s monitor has an extremely wide resolution and that sidebar which looked good on my monitor now is stretched out to maybe 450px on the other bigger resolution so now that image doesn’t fit inside of the container all nice and neat. Same goes for a an image that’s maybe 500px wide and if someone shrinks the site and the container holding the 500px image shrinks to 300px, the image protrudes out of the container now.
Images do pose a significant issue for liquid layouts (notice the minimal use of imagery on this site).
It is possible to use images and make them scale with the layout by using some of the techniques talked about here: http://clagnut.com/sandbox/imagetest/
The main problems with these techniques is that you need to use images that are suitably large enough to work on the bigger displays, meaning that the load times of pages can become slow and bandwidth costs can soar.
There is certainly no simple answer…
That’s a pretty neat tip, thanks!
I have suffered those problems before and this looks like the easiest way of solving them.
Hi Dave,
Thanks for stopping by, I’m glad this sounds useful for you.
Let me know if you release any designs that use these techniques.
haven’t felt compelled to submit a comment like this before, but this is a truly top tip, clearly explained, I can’t believe I just googled what I wanted to fix in my css horizontal menus and there was the EXACT answer. many thanks
Hi Helen,
You’re welcome and thanks for leaving a comment too.
I was running into this very same issue today and for some reason even the nowrap didn’t get my desired results. When I did not inlcude white-space:nowrap on my list item, i got the splintering you described, but when I added the nowrap I got no wrapping what-so-ever so even between list items it would not wrap. I figured out that when you add the nowrap it takes you very literally and will not wrap at all (even after itself) until it finds a space or end-line. So, using PHP to output my navigation I ended up with <ul><li><a>link1</a></li><li><a>link2</a></li></ul>
etc. This never gave the space or end-line to wrap on. Having PHP echo out a carriage return after each list item made it magically work.
Hopefully my three hours of keyboard mashing agony will be avoided in others by this little comment.
Thanks for the article.
Thanks for sharing your findings Carson.
Leave a Reply