Horizontal lists in CSS
Jun. 26th, 2010 01:36 pmIt has been suggested that someone out there may welcome an explanation of how I do menus on websites. Let's take rhmt.org as a representative example. If you take a look at the source, you'll see that the top menu is an ordinary bullet list, like this one:
The stylesheet sets display:inline on the list, which causes it to render horizontally:
me dolls links books pictures cats wishlist
Next we use the :before pseudoclass to add a separator. On Rio's site, I used a skull (☠, \2620), but ordinarily I would use a middle dot, which would have been \00B7 instead of \2620. So we set content: '\2620\00A0\00A0';, i.e. a skull and two spaces. This gives us
☠ me ☠ dolls ☠ links ☠ books ☠ pictures ☠ cats ☠ wishlist
It's put the skull before all the entries, so we set content: '' on the first entry, giving us
me ☠ dolls ☠ links ☠ books ☠ pictures ☠ cats ☠ wishlist Now we use position: absolute to put the bar at the top of the page, and set margin-left:auto; margin-right:auto; to centre it. On most designs I would then set a large margin-top and a background-image on the list, so we'd get a picture above it. But here I use border-top because I just want a black area to write the header on.
Finally we make h1 be position: absolute as well, and set z-index: 10 so it appears on top of the black area.
How do we make sure this styling only happens to the menu bar, and not any other bullet list on the page? The conventional way would be to use a class. But we're the only toplevel bullet list, so we can save having to clutter the HTML with implementation details by writing body > ul. In our design, there can be no other uls beneath the body because all the actual content lives in a div; if there might have been other uls, we could have written body > ul:first-child.
For example, we might have multiple toplevel lists because we wanted to apply a similar treatment to a breadcrumb list. In that case, you would set something like \00BB\00A0\00A0 on li:before to get the » symbol between the elements. But note that logically a breadcrumb list should be an ol, not a ul, so you might not need to use ul:first-child anyway.
- me
- dolls
- links
- books
- pictures
- cats
- wishlist
The stylesheet sets display:inline on the list, which causes it to render horizontally:
me dolls links books pictures cats wishlist
Next we use the :before pseudoclass to add a separator. On Rio's site, I used a skull (☠, \2620), but ordinarily I would use a middle dot, which would have been \00B7 instead of \2620. So we set content: '\2620\00A0\00A0';, i.e. a skull and two spaces. This gives us
☠ me ☠ dolls ☠ links ☠ books ☠ pictures ☠ cats ☠ wishlist
me ☠ dolls ☠ links ☠ books ☠ pictures ☠ cats ☠ wishlist
Finally we make h1 be position: absolute as well, and set z-index: 10 so it appears on top of the black area.
How do we make sure this styling only happens to the menu bar, and not any other bullet list on the page? The conventional way would be to use a class. But we're the only toplevel bullet list, so we can save having to clutter the HTML with implementation details by writing body > ul. In our design, there can be no other uls beneath the body because all the actual content lives in a div; if there might have been other uls, we could have written body > ul:first-child.
For example, we might have multiple toplevel lists because we wanted to apply a similar treatment to a breadcrumb list. In that case, you would set something like \00BB\00A0\00A0 on li:before to get the » symbol between the elements. But note that logically a breadcrumb list should be an ol, not a ul, so you might not need to use ul:first-child anyway.
no subject
Date: 2010-06-27 01:34 pm (UTC)Except on Internet Explorer?
Though (a) I'm not sure whether you care about that and (b) I'm not sure whether that's still true or whether newer versions are better about this corner of CSS.