Wednesday, 1 June 2011

CSS & HTML: nested lists with style

   


One common mistake that I've found in many web pages is when a nested list is needed. Usually, we think that the following code is correct:
<ul class="list">
<li>A</li>
   <ul class="sublist">
     <li>1</li>
     <li>2</li>
     <li>3</li>
   </ul>
</ul>
Producing this:
  • A
    • 1
    • 2
    • 3
which looks good. But if you try to validate the above code, you will get some errors.


Why is a common mistake
The above mistake is quite common when we want to create menus using bulleted lists. That is the reason why in the above code we used two classes for the nested list. Building a menu, we can code it as:
<ul class="menu">
  <li>Menu 1</li>
   <ul class="submenu">
    <li>submenu 1</li>
    <li>submneu 2</li>
    <li>submenu 3</li>
   </ul>
</ul>
Is that correct? No, it isn't; even if it looks ok:
I believe the mistake is made because - eventually - the page looks good anyway, but only validating the page we discover it is not correct.

The correct way
In order to make our code pass the validation process, we need to strictly follow the nesting of the list elements:
<ul class="menu">
  <li>Menu 1</li>
  <li>
   <ul class="submenu">
    <li>submenu 1</li>
    <li>submenu 2</li>
    <li>submenu 3</li>
   </ul>
  </li>
</ul>
Producing the following result:
Can you see now why we usually skip the second <li>? There's a bullet we don't really want. How to deal with that?

Styling the list elements
We can style the elements (and you were wondering why I used classes for the lists, uh?).
Styling the elements will help us to create the list as we wanted. Let's try to use something like:
<style type="text/css">
.menu {
    list-style:none;
    margin:0px 0 0px 0px;
    padding:0;
    text-indent:10px;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 14px;
    font-weight: bold;
}
.submenu {
    margin:0;
    padding:0;
    list-style:none;
    text-indent:20px;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    font-weight: normal;
}
</style>
Which produces:

  Menu 1
     submenu 1
     submenu 2
     submenu 3



And that's what we wanted our list to look like. Further styling could be related to submenus <a> tags, or change the overall look with background colours or font size, colour etc.

The above examples are just a beginning. I've used lists for menus in conjunction with jQuery to create an accordion effect. It's up to you, how to use the above hint.

Enjoy, and let me know what you think or if you have problems.

14 comments:

  1. i just realize about your ul li code
    i use mistake one :P
    thanks for the article

    ReplyDelete
  2. I'm glad you found it useful. Take care.

    ReplyDelete
  3. Thank you SO much for this. I wish I had found you hours ago - I could have saved a lot of time! :)

    ReplyDelete
  4. You're welcome Candace. Stay tuned for more... ;)

    ReplyDelete
  5. Hey there, IMO you should write nested list as such:

    <ul>
    <li>
    Menu 1
    <ul>
    <li>submenu 1</li>
    <li>submenu 2</li>
    <li>submenu 3</li>
    </ul>
    </li>
    </ul>

    ReplyDelete
  6. Michael, what you write is correct. My way or your way - I believe - are correct. The point is that all the list tags have to be closed and the nested ul must be inside a parent li. Thanks for the feedback!

    ReplyDelete
  7. The way proposed by Michael is correct. The way listed in the article is incorrect, and is why you need to do hacks via CSS. They're not both correct. Michael's is semantically much more correct than yours.

    ReplyDelete
    Replies
    1. Tom,
      there's no "hacks" in CSS, they are just examples. As for the correct or not correct, my solution passed the W3C HTML validation, so I guess it is correct.
      As for the "semantically more correct", well... I won't say anything...
      Thanks for leaving a comment... and take care!

      Delete
    2. Testing comment fuctinality

      Delete
  8. I'm an experienced web developer and found this while looking for something else about lists.
    On seeing the first paragraph I thought 'oh good.. someone telling people how to do things properly' and was about to close the tab, then I scrolled down and skim read your article only to be disappointed that you actually still get it wrong, as Michael and Marco have pointed out.

    Being valid HTML does not mean it is the correct way to do something.

    Ask yourself why do you care about your HTML being valid?
    Is is so you can impress your visitors with a nice 'Valid HTML' icon and a link to the result on w3.org? I hope not!
    It should be because you care about how accurately AI can parse your page, Google and screen-readers alike. Please if you care about making the web better, care about semantics.

    Thanks.

    ReplyDelete
    Replies
    1. Thanks for your comment. I won't comment your opinion because I have already said it more than once. By the way Marco and me it's the same.

      Delete
    2. Yes I noticed that after I submitted the comment. I meant to say Michael and Tom.

      I just think it is an important point to make so that others who may come across this article can make an informed decision.

      Delete
    3. Ok you made your point. Thanks and take care.

      Delete
  9. This comment has been removed by a blog administrator.

    ReplyDelete

Comments are moderated. I apologize if I don't publish comments immediately.

However, I do answer to all the comments.