Grow your CSS skills. Land your dream job.

Listless Navigation – Using CSS To Do More With Less

Published by Guest Author

The best part about CSS is that it allows web developers to achieve more with less. What exactly does that mean? Well, for a start, CSS allows developers to:

  • Code much, much less XHTML
  • Separate website formatting from content
  • Control as much of the website theme/design as the developer allows himself with one CSS file
  • Easily adapt website display to the user instead of the user adapting to the website
  • Change the display of our website for specific devices and special circumstances

The list goes on and on. The functionality to do great things with less code is there; it's up to the developer to code the XHTML to take full advantage of the power of CSS. One place I often see CSS being under-utilized is with navigation menus.

Depending on the design of your website, you may use vertical navigation or horizontal navigation. You may use both. If you're using XHTML lists, <ol>'s or <ul>'s, for your navigation, there's a good chance you're writing extra code. It's time to take advantage of CSS' display property. We're going to turn...

<div id="navigation">
	<h3>Categories</h3>
	<ul class="nav-list">
		<li><a href="/css">CSS</a></li>
		<li><a href="/html">HTML</a></li>
		<li><a href="/mootools">MooTools</a></li>
		<li><a href="/php">PHP</a></li>
		<li><a href="/xml">XML</a></li>
	</ul>
</div>

...into...

<div id="navigation">
	<h3>Categories</h3>
	<a href="/css">CSS</a>
	<a href="/html">HTML</a>
	<a href="/mootools">MooTools</a>
	<a href="/php">PHP</a>
	<a href="/xml">XML</a>
</div>

...using some very basic, cross-browser compatible CSS.

The only true advantage of using the list/list item method of structure, in this case, is that <li>'s are essentially "block" elements; they're solid containers that drop to the next line unless floated. CSS allows us to block specified elements using the display:block; property/value combination. To lose that bloated list code above, we can specify display:block; for any link (<a>) inside the navigation menu.

#navigation a { display:block; }

The above example is all you need for vertical navigation. For horizontal navigation, you will need to specify a float value, just as you would have with the list items:

#navigation a { display:block; float:left; }

That's all? Yes! In many cases, you can simply take the former <li> properties and move them to the link selector! The above code is a huge advantage to both the developer and the user because:

  • the developer can save a lot of bandwidth
  • the page downloads quicker for users
  • less code can mean faster maintenance
  • list properties wont interfere with your anchor properties

If you're not convinced or would like to see this CSS/XHTML in action, feel free to view the source code of my website at: davidwalsh.name.

Before You Comment...

My method has been criticized so I'd like to answer a few questions/comments I foresee.

1. This is ugly code!

I've never had a customer tell me my code was ugly. I have, however, been thanked for creating websites that load quickly. Remember that developers, in most cases, are the only ones who care about how your code looks. Functionality is the key.

2. It doesn't save that much code!

Think of how many times your page is downloaded by users! Think of the extra download time your javascript libraries add! All web developers should consider download time.

3. Your code doesn't degrade well.

Accessibility is always a consideration I take. If you were to turn off all CSS styles, the page would simply show links separated by a space. As good as a list? No, but still plainly readable.

In speaking with Chris, he brought up a very clever point. One could create a <h2> tag (or whichever you choose), call it "Navigation", and hide it using CSS. If CSS is turned off, the "Navigation" heading will display and it will be clear to the user that he/she is viewing the navigation.

I'd like to extend a special thank you to Chris for letting me share my method with you. I plan on monitoring comments so please share your ideas and suggestions.

David Walsh
The David Walsh Blog :: PHP, CSS, MooTools, and Everything Else
davidwalsh.name

Comments

  1. Romz
    Permalink to comment#

    What about accessinility of screenreaders?
    What about semantics?
    What about display:block for IE ?

  2. Mathew Byrne
    Permalink to comment#

    I’m not a big fan of this technique, mostly because you’re taking away the semantics of the HTML: instead of a structured list of navigation links we now have an ambiguous set of anchor tags that theoretically form the navigation of your page. There is no clear grouping of links and navigation items.

    Also I think that the list example you gave was slightly bloated. Having the class nav-list is probably unnecessary since the list could easily be selected with #nav ul.

    The other advantage of using a list in conjunction with a set of links is that it neatly provides some extra markup to attach CSS to, so techniques like Douglas Bowman’s Sliding Doors are possible.

    As for saving bandwidth… I guess that may help some, but shortening your id names might also give fairly similar improvements in performance!

  3. As good as a list? No, but still plainly readable.

    IsThisAsPlainReadableAsItCouldBe? Because thats how your links would appear on a browser that doesn’t support CSS (I’m thinking the mobile kind).

    Why not have all lists like that? Infact we could use a table for them…. (/sarcasm)

  4. @Romz & @Mathew: The individual “h” tags represent the navigation groupings, so to speak, so separation between different navigation sections doesn’t disappear using this system. Display:block works in all IE and modern browsers, so that isn’t a concern. I do know that shortening an ID will work, but I used a longer one for the sake of this example. A shortened element ID, however, doesn’t come close to equaling the amount of bytes that go into creating a list.

    Lastly, the above solution isn’t going to work in every situation, so the Sliding Doors example isn’t going to work using my example (unless you have different button images for each link). For many purposes, however, this solution will work.

    @James: Your “IsThisAsPlainReadableAsItCouldBe?” should be “Is This As Plain Readable As It Could Be?” The carriage returns are rendered as spaces. Your sarcasm is quite clever though.

  5. You could get sliding doors to work without using <li> elements. Just use spans as your extra hook instead of the list element.

  6. Mathew Byrne
    Permalink to comment#

    @Chris: I guess my point about having sliding doors is that it’s a bonus feature of using lists as well as having semantic markup. Sure you can use spans but the point is that spans add no structural meaning whereas a list does.

    @James: To me a list seems like a perfect way to view a set of nav items, rather than a mass of indistinguishable links, but then again it would greatly depend on the mobile device. With devices like the iPhone and Google’s Android, I think this argument is going to become less and less relevant however.

  7. Permalink to comment#

    You can also get rid of the whitespace and save a whopping 20 bytes, 168 from 188. Bytes people…
    The original is a bloated 270 bytes down to 239 bytes.

    Both show up as 4.00 kb though, go figure.

  8. Beau
    Permalink to comment#

    In one of my interface design classes, they taught us that using lists for links is proper semantics (groups of stuff put together in a relevant list). However, I’ve ‘cheated’ and not put links into lists before because it was easier to code AND style! I guess whatever you decide should probably depend on how much traffic your site is gonna get – you only cut the corners if it’s gonna save bunches on bandwidth?

  9. Permalink to comment#

    http://www.peachpit.com/articles/article.aspx?p=369225&rl=1

    http://www.csslounge.co.uk/2005/06/16/the-semantic-web/

    In a quick search I came across these two sites that explain the use of Lists instead of just links in order with out UL or OL.

  10. After i read your article, i was looking for more information about how screenreader or such things use lists for navigation and it seems that lists are very important for the understandig and the correct translation for challenged persons. So for the accessibility the solution with the titel “navigation” won´t work and i have to vote against this way saving code.

  11. Permalink to comment#

    I guess you were already expecting this kind of responde from the readers :)
    Anyway, I think it’s a perfectly reasonable way of doing it.

  12. Nathan Rutman
    Permalink to comment#

    This doesn’t achieve more with less…it achieves less with less. Losing semantic meaning and accessibility is no excuse for fewer keystrokes. That’s just laziness. I wouldn’t recommend this approach to any web developer.

    Thanks for your thoughts, though.
    -Nate

  13. My goal with this isn’t to say “this is how you SHOULD do it.” It’s to say this is how you COULD do it. I understand people use lists and I’m fine with that; I simply want to point out that many times lists aren’t necessary and that CSS gives you the ability to NOT have to use lists.

    @Chris: As far as bandwidth usage and going from 270 down to 239 bytes, the amount of space saved obviously depends on the size of your navigation menu. Then multiply that by the number of pageviews your website gets. Then multiply that number by the number of visitors you get per day. That’s the saving your frequent visitor will appreciate.

    I did expect this response — I tend to push CSS to the brink when I can. I received the same response when I posted the following on my blog.

    Sure, it may not be semantically correct, but it is effective.

  14. @Yaili: I love your blog design!

  15. Permalink to comment#

    Another addition to the hidden -tag, would be to add a hidden -tag to separate each article listing (on a front page, for instance). The article(s) title(s) should be a h1 or h2 (both for SEO and best accessibility options), but if you’d have to turn off CSS it would’ve been easier to understand when a text ended.

  16. Permalink to comment#

    Damnit. Without the preview-script, I didn’t get to see whether or not the tags would render as I wanted. Tag 1: <h2>and tag 2: <hr />

  17. Permalink to comment#

    Saving bandwidth huh? Most browsers cache local copies of pages that are frequented in history.

    I would definitely like to see a navigation with sub-navigation done this way. Think you can push it?

    Something like….

    
    Title
    
    <a href="#" rel="nofollow">Something 1</a>
    <a href="#" rel="nofollow">Something 2</a>
       
          <a href="#" rel="nofollow">Sub Something 1</a>
          <a href="#" rel="nofollow">Sub Something 2</a>
          <a href="#" rel="nofollow">Sub Something 3</a>
       
    <a href="#" rel="nofollow">Something 3</a>
    <a href="#" rel="nofollow">Something 4</a>
       
          <a href="#" rel="nofollow">Sub Something 2</a>
               
                   <a href="#" rel="nofollow">Really Sub Something 1</a>
                 
    

    What you presented is fine for a list of links that in a paragraph NOT for real navigation of any sort.

  18. To repeat what I’ve said, this wont work in all cases. To add subnavigation, for visual purposes, you’d add a class to the subnavigation items. For screenreaders, you’d want to use lists.

  19. I have written a response to this article on my site. When it comes to semantics, accessibility and flexibility this method falls short of meeting any of the requirements or recommendations necessary to accommodate anyone that isn’t a person using a computer-based browser with perfect vision (and even then it is a stretch).

  20. Permalink to comment#

    I also had a thought, it most likely wouldn’t work with a sitemap page either. I hope if it IS used on a site that you include a proper sitemap.

    While I appreciate the “edgey” css, I just don’t think it does well for the site called CSS tricks. It’s not CSS-Mistakes and we shouldn’t be teaching bad semantics, xhtml and css coding.

    There’s a difference between pushing the envelope and breaking it. Just happy so many people left their comments on the matter for archival purposes.

    XHTML 2 will have the new elements NL and LABEL, won’t that be nice! However older browsers won’t support it. But fortunately almost all browsers support UL, OL and DL.

  21. I’d like to continue playing the devils advocate here, because I think this is an interesting conversation.

    The term semantics is being thrown around a lot here. I have my doubts about how well an unordered list semantically describes navigation links. Lists are great for things you need for a recipe or a step-by-step of how to take apart your carburetor, but I’m not sure page navigation requires it.

    Semantically, the navigation needs to be “wrapped” in something. I know divs get misused and overused way too much, but I would argue a “division” here is just as semantically appropriate here as an unordered list, if not more.

    The more important consideration here is accessibility and how this navigation is going to look with CSS on and with CSS off. I threw together a quick example of a page navigation that I think does a find job on both counts.

  22. The only problem with using a div is that a div is used to divide a page into sections. Currently the most semantic way to list out navigation is in a list. It is a list of navigation links that will take you to other places in the site. Like Chris S. said, XHTML 2.0 will come out with more semantic ways to do it. That is, if HTML 5 doesn’t beat it.

    The whole future of web design markup sure is getting confusing, as an off note.

    At any rate, currently the most semantic markup available would be a list for navigation. In my opinion at least.

  23. @ Chris S: My sample code qualifies as a trick to me — achieving a result with less code. Realize that this site isn’t “CSS-Standards” or “CSS-Recommended-Semantic-Practices”either. You’re placing far too much “stock” into this. This is an article showing what styles CAN do, not what you SHOULD do. One of my goals with this article is to play devil’s advocate — fresh ideas aren’t necessarily created by following the rules.

    @ Chris C: Thank you for posting an example — hopefully that will make things a bit more clear.

  24. Just a note, not about the article but actually about your bullet lists. The bottom part of the image is missing. If you need a screenshot, please let me know!!

    In using firebug, I noticed that on line 170 (i think) the line height for the li is 1.5em, I tried 1.7 and it showed the image bullet fully.

    .post li {style.css (line 170)
    font-size:1.2em;
    line-height:1.7em;
    margin-bottom:0.9em;
    margin-top:0.5em;
    }

    Hope it helps

  25. jimminy
    Permalink to comment#

    Well, I am almost completely new to designing pages and I came up with David’s technique on my own. I had used lists for navigation on the first page I ever made from ‘scratch’, but then decided I wanted a horizontal navbar on my next practice page. Instead of tricking a list, which is usually vertical into being horizontal, I just decided to put the navigation links inline within a bar.

    Of course, if you are making something more complicated the code will need to be more complicated, but for a basic navigation bar, I think the technique David laid out works quite well. Like David said, it displays the links separated by spaces and with CSS turned completely off still looks perfectly fine. If the ScreenReader starts off by saying “Link Home”, etc. I think the user will be quick to pickup on the fact that it is a navigation area.

    From the perspective of someone new to page-design the use of lists seems to have it’s own problems, it may be that fulltime designers have simply become accustomed to these issues. While this technique may not be applicable to all designs, it will work for some people.

  26. PXLated
    Permalink to comment#

    After reading several posts on this subject, I’m not sure I agree that lists are necessarily better than a div. One can look at their navigation as a list of links or as a block of buttons. Since there currently isn’t a specific tag for nav elements/items, it seems to me that it’s just shoehorning nav into something that is currently available. Does that make it semantic/meaningful? Since it isn’t a “standard”, to me it’s more a theory or personal opinion then a semantic absolute.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".