Bulleted Lists: Multi-Layered Fudge

Designing our company’s website in CSS was coming along nicely until I hit a roadblock. The challenge was to create two columns of bulleted lists in the flow of the text. The layout I had in mind was something like this:

Article Continues Below

Paragraph 1
Bulleted list | Bulleted list
Paragraph 2
Bulleted list | Bulleted list
Paragraph 3
Bulleted list | Bulleted list
…and so on

I tossed around some lists that worked fine in IE 6, but caused a headache in almost every other browser. Perhaps I could have smashed through the roadblock using horizontal lists. But I’ve always found it easier to float, so that’s what I did.

Floating ULs#section2

To solve the problem with floats, let’s assign two classes of unordered lists, ul.left and ul.right, which we’ll place in a div named “div” that’s 800 px wide (yes, 800 is just an arbitrary number; you can set it to whatever width you want). The basic CSS reads:

  #div {width: 800px;}
  ul.left {float: left;}
  ul.right {float: right;}

For the markup, we’ll use three paragraphs of Lorem Ipsum text, slot in the unordered lists, and place the whole lot in the div. The markup looks like this:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud.

  • Item 1: Left
  • Item 2: Left
  • Item 3 Right: A long item
  • Item 4 Right: This is longer, just for fun

Duis aute irure dolor in reprehenderit in voluptatevelit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.

  • Item 1 Left: Varying length
  • Item 2 Left: This one varies in length, too
  • Item 3 Right: This is shorter
  • Item 4 Right: Right

Pellentesque et erat. Quisque at quam. Donec accumsan tellus at tellus. Donec metus. Sed sit amet ante vitae metus imperdiet varius. Vestibulum pulvinar bibendum.

  • Item 1 Left
  • Item 2 Left
  • Item 3 Right: Another long item
  • Item 4 Right: Right

The trouble with Dilbert#section3

The trouble with our UL floats is this: the text of the paragraph below creeps up between the two floating ULs. Also, the UL floating right loses alignment.

To overcome this, we’ll do three things:

  1. Set the margin, padding and border to zero. This is for consistency, to prevent browsers from meddling with the alignment of our bullets with different “default” padding / margins.
  2. Specify the bullets. Again, this is to maintain consistency across browsers. We’ll use simple square bullets.
  3. Declare the width of the ULs: Here, we’ll assign an arbitrary width of 400 px for each UL, half the width of the containing div.

The CSS now looks like this:

  #div {width: 800px;}
  
  ul.left {
    float: left;
    width: 400px; 
    margin: 0px;
    padding: 0px;
    border: 0px none; 
    list-style-position: inside;
    list-style-type: square;
  }
  
  ul.right {
    float: right;
    width: 400px; 
    margin: 0px;
    padding: 0px;
    border: 0px none; 
    list-style-position: inside;
    list-style-type: square;
  }

The spacing gremlin#section4

IE 6 leaves an equal amount of space before and after the ULs. However, later versions of Mozilla (1.7.3), Opera (7.54) and Firefox (1.0) leave space before the ULs, but none after. To ensure that the space before and after the ULs is equal, we’ll assign a padding of 15px to the top and bottom of the ULs, like so:

  #div {width: 800px;}
  
  ul.left {
    float: left;
    width: 400px; 
    margin: 0px;
    padding: 15px 0px;
    border: 0px none; 
    list-style-position: inside;
    list-style-type: square;
  }
  
  ul.right {
    float: right;
    width: 400px; 
    margin: 0px;
    padding: 15px 0px;
    border: 0px none; 
    list-style-position: inside;
    list-style-type: square;
  }

IE 6 is happy. There’s some space left after the ULs in Mozilla, Opera and Firefox, but the space before and after the ULs is still not exactly equal. This uneven spacing is a result of the default space left after the preceding paragraph, so it’s the paragraph that needs defining to correct this. Defining the margin or padding at the top of our ULs will not solve this problem. 

We want to cook our fudge to perfection, so we’ll add a paragraph class and called .no-space and set its margin and padding to 0:

  .no-space {
    margin: 0px;
    padding: 0px;
  }

We’ll also change the markup to include this paragraph class:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

  • Item 1: Left
  • Item 2: Left
  • Item 3 Right: A long item
  • Item 4 Right: This is longer, just for fun

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat.

  • Item 1 Left: Varying length
  • Item 2 Left: This one varies in length, too
  • Item 3 Right: This is shorter
  • Item 4 Right: Right

Pellentesque et erat. Quisque at quam. Donec accumsan tellus at tellus. Donec metus. Sed sit amet ante vitae metus imperdiet varius.

  • Item 1 Left
  • Item 2 Left
  • Item 3 Right: Another long item
  • Item 4 Right: Right

Now it seems everyone’s happy, more or less. We’re almost done.

It would look better, though, if the left column of bullets was indented, rather than being stuck to the left margin. To achieve this end, we’ll do the following:

  1. Declare relative positioning for the left UL.
  2. Specify its distance from the left. In our example, let’s make this distance 50 px.

The CSS now reads:

  #div {width: 800px;}
  
  ul.left {
    float: left;
    width: 400px; 
    margin: 0px;
    padding: 15px 0px;
    border: 0px none; 
    list-style-position: inside;
    list-style-type: square;
    position: relative;
    left: 50px;
  }
  
  ul.right {
    float: right;
    width: 400px; 
    margin: 0px;
    padding: 15px 0px;
    border: 0px none; 
    list-style-position: inside;
    list-style-type: square;
  }
  
  .no-space {
    margin: 0px;
    padding: 0px;
  }

Things are looking good. That’s it from me, really. Oh, and you can view the page that gave me the two-list headache in the first place. The technique used there is quite similar.

I hope you enjoy the multi-layered fudge. Add your own yummy gif bullets and serve piping hot!

About the Author

Nandini Doreswamy

Formerly a surgeon, Nandini Doreswamy is now a systems and wireless LAN engineer living in Auckland, New Zealand. Her passion for web standards emerged when she designed websites for the two companies she owns and operates, Radius Networks and Helion Training.

81 Reader Comments

  1. classes like “left” and “right” are not good names to begin with, furthermore, chopping a list into two is another bad thing, because we are dealing with single lists here.

    In this case I’d rather go for absolutely positioned li’s in one ul

  2. I like the way this is handled. I was recently talking about doing something similar on one of our sites and was having some issues with things lining up like this.

  3. in your example, all of the

    elements get the class – wouldn’t it be easier to use a #div p selector?

  4. I don’t know if its right, but i would have gone for one ul set to a fixed width and the li’s set to half the width and to floatnext to each other. That way you would get the look of two lists from the one, without more css than necessary. But hey, thats just my opinion.

  5. Why not have it in one list (instead of two), float all li, but give them a width of 50% (thus making sure there are only two list items per row)… Haven’t tried it, could that work as well?

  6. There are a couple of things wrong with this article.

    The classes have been used somewhat injudiciously. A better choice would be to use descendant selectors.

    Based on the “example in the wild” Nandini posted, I would say that semantically, there is only one list, which needs to be displayed in a particular fashion.

    My approach:

    http://mechavox.com/sandbox/layeredfudge.html

    was to wrap the content in a container div and use descendant selectors to apply styles. There is only one list between each paragraph. The ul’s have a fixed width and the li’s are floated. You can see this in action at the above example.

  7. Paired lists where one is longer than the other. I saved the example to my hard drive and added an extra bullet to the right list in the first pair and an extra one to the left list in the second pair.
    View the new sample here

    The whole thing breaks down in IE and FF. So this is only good for lists containing even numbers of elements.

  8. Stephen’s example just above does allow for odd-numbered lists and so it works quite well.

    However, what if the client requests that the items be numbered? They’re not going to want the numbering to jump back and forth like that. Anyone got any ideas?

  9. floating li’s results in lists like

    1 2
    3 4

    where the authors goal was

    1 3
    2 4

    this could only be achieved with absolute positioning (or css 3 float: top / column layout)

    the spacing problem is one induced by floating the ul’s, which should not be solved by altering default p behaviour.

  10. I’m not convinced.
    I’d like to keep all of the classes for this technique confined to a div tag just for them, otherwise it would be difficult to implement it on a site-wide stylesheet. I also agree about the excess of class tags. This example is also not very size-flexible.
    See http://www.ryancannon.com/lib/html/layeredfudge.html
    I’ve done a couple of things:
    * Relative widths allow these lists to be put anywhere
    * Use of margins on the list items instead of relative positioning the list will keep the lists from overlapping
    * Fewer class attributes at the cost of a br tag for each group–wouldn’t need it (or class=”second”) if the sibling selector was more widely supported.

    Thoughts?

  11. This article seems to miss the point of using CSS altogether. You might as well have placed them into some TD’s or turned the thing into an image (al a 1995) and been done with it.

    I’d agree with other authors that the best approach would have been a single list – now if someone could come up with some tricky code for correctly positioning the LI’s as desired in this article, that would be bonus man-points.

    • Item 1 Left
    • Item 2 Left
    • Item 3 Right: Another long item
    • Item 4 Right: Right

    in conjunction with:

    ul.distribute {
    position: relative;
    height: 2em;
    margin: 0;
    }

    ul.distribute li {
    position: absolute;
    }

    ul.distribute li.row1 {top: 0em}
    ul.distribute li.row2 {top: 1em}

    ul.distribute li.col1 {left: 20px}
    ul.distribute li.col2 {left: 320px}

    this allows much more flexible (re)positioning of things, it also allows strange layouts like organisation charts (I used a similar technique for a company once)

    Now is this equal to putting things in tables, well, I admit it’s getting close, ’cause the classes I used are not the most semantic I guess…

  12. > Rikkert Koppes

    What happens in your solution if the line is long and is forced to a new line? You’ll have the second LI text right on top of the first LI’s second line text.

    The problem with relative positioning is that it cannot be guaranteed to render well in all browsers. The solution proposed in this article addresses this issue. While yes, I agree there is an overuse of class names when selectors could work just fine, I don’t think the “tearing apart” of this author’s article is called for.

    For everyone proposing their own supposed better solution:

    Did you test in multiple browsers?
    Did you test with long strings of text vs. small strings?
    Did you test if the text carries over to a new line?

    I’m pretty sure Nandini did.

  13. Let’s say you have a deadline creeping up, you cannot make predictions on the length of the list items, and the client wants it to look the same in all browsers (>or=5). Why not a simple table?

  14. I agree with the rest of the folks on here in that there’s no real reason to split the unordered lists up into left and right. But if you have to do that, at least be smart about it.

    Change this:


    ul.left {
    float: left;
    width: 400px;
    margin: 0px;
    padding: 0px;
    border: 0px none;
    list-style-position: inside;
    list-style-type: square;
    }

    ul.right {
    float: right;
    width: 400px;
    margin: 0px;
    padding: 0px;
    border: 0px none;
    list-style-position: inside;
    list-style-type: square;
    }

    To this:


    ul.left, ul.right {
    float: left;
    width: 400px;
    margin: 0px;
    padding: 0px;
    border: 0px none;
    list-style-position: inside;
    list-style-type: square;
    }
    ul.right { float: right; }

    See, wasn’t that easier?

  15. As text is resized in the user’s browser, the text begins to overlap and do all sorts of crazy things (I’m referring to the finished example given in the article). Actually, after the second paragraph, ”
    # Item 2 Left: This one varies in length, too” runs right into “# Item 4 Right: Right” without me changing the font size at all.

    I’m using FF 1.0

  16. not only are the classes non-semantic, but a simple list was broken in two. why?

    a table is just as good as breaking one list into two for the purposes of PRESENATION in the structural layer.

    have we gone from reading about improvements in our process and approach to saying that this is a “practical approach to the current environment” or in other words… hacks?

  17. We have done this sort of thing for a few clients. Usually we use one list and do what the others have suggested with floating the li’s with 50% of the width of the ul. ( Or dd’s floated in the dl as is most often the case.)

    The only problem with the lists are instead of reading down in columns, they read left to right. That is:

    1 2
    3 4
    5 6

    not:
    1 4
    2 5
    3 6.

    However, that is a small price to pay. Visitors usually catch on to the order- Even if it is a long list in alphabetical order.

    With small list like the example, I would argue the order is even less of an issue.

    Therefore, I say go with one column not 2! It’s more semantic.

    David

  18. I tried out alicia suggestion and it works fine
    ol
    {
    width : 100%;
    }

    ol li{
    width : 50%;
    float:left;
    }

    The only downside is that items are drawn so the first is on the left and the second is on the right instead of them being drawn first for the left and then for right, does that make sense?

  19. A table is no better or worse than breaking up the list into two lists. A table has rows and columns, and they have a certain understood relationship. Semantically, I’d much sooner have the content in two lists that marked up with a relationship that isn’t there, i.e. the row/column relationship.

    There’s no perfect solution, and the author offers one that works. It has its problems, but so do all attempts at making an imperfect markup language and an imperfect presentation syntax (along with imperfect user agents) work for practical needs.

  20. Apart from the discussion on semantics, if one just goes with the markup proposed in the article, the following CSS should also work just fine in a cross browser kinda way:

    #div { width: 800px; }
    #div * { margin: 0; padding: 0; }
    #div ul { position: relative; margin: 1em 0; width: 400px; float: left; }
    #div p { clear: both; }
    #div li { margin: 0 0 0 2em; }

  21. Why bother with two lists and classified paragraphs? Floatting

  22. ‘s in a single list as mentioned above would be enough to reach the same effect, but correct semantically and for people with css disabled. No problems of two UL’s width and margins, just one padding and margin setting in the main list and some rule for the li’s… and less problems with paragraphs too.
  23. if the html is semantically incorrect like this, then what was the point in using webstandards in the first place?

    i see no benefit in this method, sorry

  24. Is it just me, or have the overall quality of ALA articles gone down over the last year or so? I almost seems as if this article was written just to get to the final link to the services page for her company. But if you look at this page, there is no reason to separate these into separate lists. The floated, 50% width LI solution that many have proposed (and that I actually used on a site a while back) would work just as well, be more semantically correct, and be simpler to maintain.

  25. Sorry, now I understand the vertical order of the items was the goal of the article, but IMHO if you really care of what is your reader reading order or direction… just make an old fashioned single column list. Splitting it (I mean visually) in two columns, don’t assure you what direction your reader is assuming, it can vary from nationality, instinct etc.

    Ok, let’s consider that you really want it:

    1 3
    2 4

    why don’t simply write

  26. s in a different order and use a single ul with lis floatted? ok, noCss users wil read it in a different order, but you can make a choice estimating the non-css percentage of your users. An Most of all… is that list a truly ordered one? Does it explain ordered steps of a process? It’s an unordered list and so I think it’s possible to shuffle items without losing interest.

    About the table, it cannot be the correct way (even if the easier). The content of the articles list semantically represents a list, not a table… it hasn’t row-columns relationships as could be in a leaving-arrival table in the train station. A single column table is simply not a table.

    Ok, finished (sorry for bad eng.)

  27. The thing that frustrates me about this, and many other, techniques, is all the fiddling required to counteract default padding (the no-space class, etc).

    I guess there’s no answer here, as browsers implement different defaults, but all the “compatibility” CSS styling (as opposed to “presentational” styling) hides the basic intent of the stylesheet. And when you have to add classes to the HTML markup, that’s even more intrusive 🙁

    I’d love to see an article on how to work around browser defaults like this in as non-intrusive a manner as possible.

  28. Having a list in the order…

    1 2
    3 4

    …can be handy for long lists. It means you don’t have to scroll back up the page once you’ve read to the bottom of the first column.

    As for the article, I agree it’s not a great method but it’s sure prompted a lot of people to do their own experiments. That’s great.

  29. This is were we need to use the nth-child selector 🙂
    You can have a one-list, semantic correct solution if you used it.

  30. the list order shouldn’t matter anyway, ’cause we are playing with an unordered list, so all the float examples do comply, but I guess for further discussion let’s assume the order is of importance and we’re dealing with an ol.

  31. What if I am using lists to list product features, steps in a process, etc. and I need a paragraph of text giving some explanation or background between items 3 and 4?

    How many developers here would split the items into list-paragraph-list, and how many would keep them all in one list, use CSS to bump up the spacing between items 3 and 4, then absolutely position the paragraph between them?

    I’m not sure I’m happy about using two lists for a purely visual effect, but in my example above, I would easily put myself into the first group of developers. Not only is that solution easier to implement, it has a much better chance of consistently communicating across various browsers, screen sizes, and user font-settings.

    Where do we draw the line between semantic purity and effective communication? Will splitting the list cause a difficulty in screen readers or indexing devices? At what point can I allow other considerations to outweigh semantic purity “for the principle of the thing?”

  32. I agree with Pierluigi Pesenti. This was by definition an *unordered* list, meaning that the *order* of the items did not matter.

    However, this may be being a bit pedantic.

  33. I’m surprised no one has figured out how to make it look like this yet:

    1 4
    2 5
    3 6

    CSS3 actually provides a perfect and elegant solution.

    Literally ALL you need to do is:

    ul{ column-count:2; }

    See it in action at http://www.xs4all.nl/~berendse/ala/listfudge.html

    Unfortunately, Mozilla-only, of course ;), for now…

    Another thing that’s great about this, if your IE doesn’t get it, it will still look just like a regular list. No weirdnesses in your styles because of incorrect floats!

  34. Seems like a perfect situation to use javascript because it preserves semantics, while providing the desired visual effect. My strategy is to use DOM to replace the list with a div containing two lists. Set class names on the lists and the div to ensure the css doesn’t affect other elements that shouldn’t float. Keep the css as is, but use contextual selectors.

    http://chriscassell.net/projects/js/layeredfudge/

    Works in (at least) Safari 1.2, Firefox, IE6. Obviously, it could be encapsulated and genericized a little more, but it’s just proof of concept.

  35. I agree. Javascript is the way to go here.

    Imagine how this page would look on lynx or with CSS disabled: like two confusingly-separated lists. I suggest that one ul is used, and the javascript DOM finds all li’s within the ul. It should count them and float the second half to provide a list like this:

    1 4
    2 5
    3 6

    Or it should just float every other li to create one like this:
    1 2
    3 4
    5 6

    This method uses HTML, CSS, and javascript appropriately. HTML only for markup, CSS only for the look and feel, and javascript to add an extra, yet not necessary or relied-upon, touch.

  36. I have to agree with Chris Cassell’s aproach to separating lists for the purpose of presentation – lets avoid the bizarre code and CSS hacks, and let JavaScript do it. Isn’t it ironic that this point has to be made again so soon after PPK’s article on Alistapart?

    Barring a successful way to implement this with JavaScript, there is no reason other than stubborn CSS-geek orthodoxy not to do this with a table. I understand that the list items are not meant to be regimented into row-column logic, but a table can produce the desired reading order without the fuss, even for the visually impaired. If we really need to order the lists,

    1 3
    2 4

    simply put 1 & 2 in the same cell and 3 & 4 in the other and be done with it. There are more important things to worry about, like no pro hockey this year.

  37. Thank you all for the constructive criticism. I’ve learned a lot.

    I do have a couple of questions, though. At the start of the article, I’ve said that I had bulleted lists in mind. Aren’t bulleted lists, by definition, unordered lists, as opposed to numbered lists which are ordered? Also, I would really like to learn more about what’s wrong with the semantics. Is there any reference where I could read more about this?

    I feel compelled to respond in particular to Joe, who commented, “…seems as if this article was written just to get to the final link to the services page for her company.” (‘swing and a miss’ – 17th February). The service page in question deals with computer systems and wireless LANs in Auckland, New Zealand. Surely, getting hits from serious web designers from around the world would not be the way to get more business in these unrelated fields. I rest my case.

    Thanks again.

  38. We found one answer with floats, one with javascript, and one with a widely unimplemented web standard. And your approach is still headed in the right direction if the lists are truly different lists.

    You could also maintain a single, classed, but unstyled list in your content management system, and have your page building software transform the single list into anything you want. That would make maintenance easy, but break the semantic purity for readers. In some cases, readers might not care.

    The part of the discussion that strikes me is that the order of items mattered to people, even though it was supposedly an unordered list.

    I wonder, then: If I list items alphabetically, is this not an ordered list? And isn’t the number associated with an item purely presentational — not ‘semantic’?

  39. not sure what you mean, but I’ve written an article about class and sematics once: http://www.rikkertkoppes.com/thoughts/class-and-style

    while that’s most about classnames, there’s another thing about splitting the list and the discussion about ordered and unordered lists as well.

    Well, in case of unordered lists, the order sould not matter at all, so every order should be ok, including floated solutions. In case of a preintended order (alphabetically, in order of importance or anything else), your problem is one that could not be solved with ordinary (2.1) CSS (except for absolute positioning as I mentioned), CSS 3 however, will fix this with the column construct, which will probably be implemented with FF1.5 (but that’s another story).

    As I see, the only way to solve this problem is to do it with absolute positioning, as I’ve sais before. The reason I brought this up is the resempblance with another problem (organisation charts), about whitch I will publish an article in the next few days

  40. Thanks for that, Rikkert. I read your article on classes with interest and gleaned some information about semantics from the W3C page you’ve linked it to.

    Just one suggestion – you may want to validate the CSS on your site (default.css at http://www.rikkertkopes.com) and the HTML markup for your article at http://www.rikkertkoppes.com/thoughts/class-and-style , as there are several errors coming up in both, in W3C’s validator.

    Thanks again.

  41. [offtopic:] The fun at of reading ALA is vanishing rapidly if the first four pages of comments contain nothing but slashing authots, complaining about ALA article standards etc.

    If you like to play the part of the two old men at the balcony in The Muppet Show, shouting ‘boo’ at every act, that’s fine. The problem is that you are not half as funny and you make the audience leave the theatre in the end. Please, open up your own theatre if you are so shocked by the low quality of ALA[/offtopic]

    I’m interested in the javascript versus two UL-list solutions:
    – javascript:
    When CSS is turned off you still have a split list, which I guess is fine since it will flow with the text. But what if the screen is really small and a CSS float would force the ul’s the be stacked upon each other, which is the behaviour you want, what will happen to the split list?.
    When javascript is turned off, the result would be one long list, which is not what you intend, but would still be readable and workable within the layout.
    – CSS: When CSS is turned off the ul’s would be stacked up vertically in the right order. I guess this is requested behaviour and would leave the flow of text intact.

    Are there any other considerations? And what would the unobstrusive javascript solution look like?

    @arnoud berendsen: your example shows one list in Firefox 1.0, not a split list.

  42. My complaint about the semantics of your solution would be that you use two lists while it is actually one.
    The point of semantics is that the document itself represents the structure of the data and should not contain anything that implies something visual. In other words it should group data but not specify what it should look like. So it should not say wether text should be big or bold, or in our case tell if the list should be displayed in two columns. If you would look at the document without CSS there would be two lists while it essentially is one.

    If I say that the document can’t specify wether text should be big or not, I mean that in a entirely presentional way. It should specify that the text is a header for example, which would in most browser display in a bigger font. Same goes for italics or bold, if you emphasize text it will be displayed in italics in most browsers, strong emphasis is often displayed as bold text.

    The problem with your classnames is that you specify ‘left’ and ‘right’, which basicly controls the visual aspect instead of structural.

    @ Martijn:

    I don’t agree that arguing over the quality of the articles is useless or offensive.
    This article needs improvement and that should be said. We all learn from this discussion and excellent alternatives have been proposed.
    What does bother me is the continuous repeating of “let’s do it with a floated li with a width of 50%”

    So to get back on the main issue here, I’ve done this in the past by floating li’s with a width of 50% – oi I’m contradicting myself in the above paragraph.
    For unordered lists this is in my opinion the best solution since order is not important. After a quick thought I believe for ordererd lists a unobtrusive Javascript would do the trick because we preserve semantics. if I have time I will test this and post the results and a script.
    I do have to reconsider if it’s a good idea to split ordered lists anyway.

    To conclude I would like to thank the author for posting this since a useful discussion has been initiated. As a sidenote I think ALA should’ve used their new icon to emphasize on the non-pure semantics.

  43. I posted a similar article to this on my site asking how to arrange a split list. My problem was using two horizontal table cells and one list split between them. You may be interested to read the various solutions readers came up with in the comments:

    http://www.designdetector.com/archives/04/02/AQuestionOfHTMLPart2-SplitLists.php

    Regarding the article here, I would initially have considered a table. Since the list isn’t a numbered one, the order is irrelevant. So just put each list in a separate cell. This will also work when CSS is turned off.Otherwise the layout is broken, using the solutions posted here, as the list becomes a single column without CSS.

    I would not consider using JavaScript here, as the user may well have it turned off. (Again the layout will be broken and a single list will appear.)

  44. I don’t want to sound offending or arrogant, but I think you got it all wrong; the layout *should* be broken without CSS because HTML isn’t supposed to show layout in the first place.

    Using tables is even worse, like said before these list-items are not tabular data. It’s just a list of items, where a table is not. Consider the unstyled document, it should display a list (who cares if it’s split up in two rows, it’s still a list) and not a table, where the user would except some sort of relation between the items (a table should always have a header explaining the meaning of the data, which we do not need here).

  45. is: users (also applications – like a search engine) with CSS turned off usually say: “give me the data and not the design”, so be nice to them and give them what they ask, don’t go and split up lists in two if it’s actually one.

  46. @Arikawa:

    Another way to reset the default stylesheets is to define a default for all elements. W3C has a basic version of this for HTML 4 at http://www.w3.org/TR/CSS21/sample.html
    It may be a bit weighty, and there are some you’ll have to fix to be cross-browser compliant (abbr, acronym, br and remove the BDO section) but it gives you the most control.

  47. The design by Nandini seems to be fine to me. Just because there are multiple ways of designing doesn’t make one wrong or right as long as it conforms to web standards.
    The page was designed as an unordered list for 4 items- not numbered. Seems many posters are more interested in posting their “grand way of designing”.
    The amount of harsh attention this article has received is unnecessary.

    Can you do it differently? Sure, but isn’t that the beauty of design?

    Does it work in multiple browsers? YES.

    Does it meet what the client’s needs? YES.

    Does it slow the page load down to a point where users will leave? NO.

    You all are getting lost in the dot-and-tittle over a few bytes- you’ve wasted more space and energy than is necessary (I am speaking to the negative posters, not the ones who have kindly offered other possible solutions). To the positive posters: thank you for your continuing development of the CSS/Web standards community.

    To the negative space-wasters: Stop posting just to hear yourself talk. Learn what you can from the article and move on.

    Thank you Nandini for posting an interesting solution approach to this design. Good luck with your endevours and keep posting.

    ALA: keep posting these articles because I can learn something new from everyone.

  48. First off, I suppose I should take a position on the best solution so far; mine is: http://www.unbf.ca/altiustu/upload/multilayer/ If you are going to split a single list in 2 and label one “left” and one “right,” the lesser evil is certainly to preserve a single list and label individual LIs as “left” or “right”, no?

    But the larger question, in the larger context of ALA, is the way a solution is presented. I think that we can see from teh responses thus far that to be presented a solution such as teh article proposes as somehow DEFINITIVE or as a BEST PRACTICE defintiely puts the reader’s teeth on edge, preparing each to respond aggressively to faults. I mean, the article’s technique is no “Sliding Doors,” as I am sure most will ackowledge.

    I, for one, would be much more interested in articles such as these being presented as a conversation starter, encouraging the ALA community to propose their own solutions (as many have done here). If the author were to ackowledge at the beginning that s/he recognizes the drawbacks to splitting a list between ULs and requiring presentational class names, and that this solution proposed here is nothing more than one attempt at a solution, I think the community would respond more positively, and with no fewer great proposals of their own.

  49. Friends,

    Disagreement about techniques and passionate discussion about alternatives are healthy and productive. Hyperbole and personal attacks are not. The perpetrators of the latter seem inclined to hit-and-run tactics, and probably won’t read this. So instead of spending a lot of time on them, I want to thank you, our regular readers and contributors, for helping keep the forums professional, civil, and focused.

    You’re the reason our authors spend unpaid hours developing and writing and testing for ALA articles, and why it’s worth it for our also-unpaid staff to keep making the magazine go.

    Based on the number of proposed alternatives to Nandini’s technique we’ve seen posted so far, it’s clear that there isn’t a consensus on the One True Way to solve this design problem. Happily, the article and forum will provide a great resource for people who need it.

    Finally, one word to the less-helpful participants. The inevitable comments about ALA’s decline don’t make much of an impact on the magazine’s staff, but they do tend to derail the conversation and take focus from the article / techniques under discussion. If you feel strongly about it, please contact the crew directly or take it to your own site. If you’re just letting off steam in public for kicks, you’re wasting everyone’s time.

  50. Josh, you posted while I was writing the above. You might want to read http://www.alistapart.com/articles/wayitssupposedtowork/ , which we published only a few weeks ago.

    In Nandini’s article, as in most ALA articles, an author is explaining his or her own solution to a problem. No one’s presenting it as definitive or sacred, and certainly not as infallible — and if we didn’t want collaboration and discussion, we’d close the forums.

  51. Holly bergevin and I did a piece on this idea some time ago:

    http://www.communitymx.com/content/article.cfm?cid=27F87

    ..but we did not originate the idea, we lifted it from Paul Novitski:

    http://novitskisoftware.com/test/multiplecolumnsEms.html

    ..and also Alex Robinsion:

    http://www.fu2k.org/alex/css/cssjunk/ListColumns.mhtml

    In fact another author independently wrote about it elsewhere, the same week we did.

    Personally, I like the idea, but the small height variances from col to col kinda ruin it for me. Oh well.

  52. waitaminute–

    the author QUIT surgeory to become a systems engineer?! (as if new zealand wasn’t small enough…)

  53. I’ve got a solution (untested) for making the list run vertically and split, without splitting the element:

    td {
    width: 50%;
    position: absolute;
    /* set margins, list styles, etc. */
    }
    td+td+td { /* two items in first column */
    margin-left: 50%;
    }

    Two main problems: the code needs to be modified for different sized lists, and it uses adjacent selectors, which IE doesn’t support (though I think IE7.js could fix that). The second column also needs to be longer than the first to avoid the following paragraph from overlapping the absolutely positioned left half. Though margins could be used to work around this problem.

  54. One very very easy way to ensure that you’re properly marking up your content semantically is to completely ignore presentation (layout, styles, etc.) until you’re finished writing the content.

    Mark up the content properly, assign ids to each division, and you can style it with CSS later.

    This avoids problems with splitting a single list in two, adding presentational classes like “left” and “right” (What if you styled them to put the left class items on the right and vice versa? How does the markup make sense then?), and enables you or someone else to alter the layout simply by changing the style sheet – for a redesign you should not need to touch the content code.

    There’s no need to break up the lists in two here. If you’re already resigned to altering the content markup then what’s wrong with floating the list items and reordering the list manually (or via javascript)? Isn’t that faster, easier, and cheaper (not to mention semantically more correct) than the proposed solution in this article?

  55. A request to all authors of articles to be published here is to make your articles *much* better exemplars to those out there learning from them:

    Don’t use px sizing!!!

    Please. No really, it’s bad.

    For poor schmucks like me who actually have a nice, high-res monitor, I can only see about 6 or 7 words across in the 597px defined as being the width of the ALA main column.

    Similarly, the examples in this article hard code the list items to 400px wide in a 800px wide box… with 15px padding.

    Surely, we’ve all learnt to use percentages and the occasional ’em’ or ‘ex’ by now? This is about basic usability, not fancy formatting.

  56. First, I’m not frank.
    Second, many of the “what if the client wants it this way” or “that way” statements don’t apply to this article. Why? Because it appears the author’s client wanted

      s, not

        s. As a developer we have to use judgement and treat each design differently when we’re laying it out. This is one way of doing it, although I would have simply used • and discarded the use of the

          and its

        • ‘s entirely- yet its nice to know that there is more than one way to utilize
            .
            Third, I love this site. Keep it up.
  57. I have one question which is not directly related to this article, but to the site you mentioned at the end of your article (and I’m asking because I suppose that you’ve designed it). The question is:

    On the top of this site you can see some links: “home”, “products”, … Next to each link there is a small icon. These icons are not part of the html, they are defined in the CSS and they are displayed as background images. This causes one serious problem: If you print the site, these icons do not appear!

    I wonder if there is a solution to this problem (of course I can tell my browser to print background images, but I want a way the designer can influence the printing behaviour with CSS).

    The same problem occurs to many style sheets shown in the CSS Zen Gaarden: Most style sheets replace some headlines with graphics. These graphics would never be printable because they are background graphics.

    If anyone has a solution to this problem, I’d love to read it in a new article for ALA.

  58. The solution for getting columns of list items really is simpler than all of you are making it out to be. Moreover, you can do “in order” if you wanted.

    In fact, this is a fairly common request, so common that it lead to a faux-column example:
    http://cssirc.com/codes/?code=30#ordered-columns

    The solution is fairly simple:

    #ordered ol, #ordered li {
    	margin: 0; padding: 0;
    	display: block;
    }
    #ordered ol { 
    	position: relative; 
    }
    /* creates the "first column" */
    #ordered li {
    	float: left;
    	clear: left;
    	width: 50%;
    }
    /* creates the "second column" */
    #ordered li.col2 {
    	/* basically UNDO everything set above */
    	float: none;
    	clear: none;
    	width: auto;
    }
    
  59. First, there’s no requirement of balance. That is, you can have arbitrary numbers of “elements” in each column.

    Second, since this is for demonstration purposes only, and since IE doesn’t understand complex selectors, it uses simple class names to set off the alternate column. It would probably be more helpful to distinguish them more descriptively.

    Lastly, IE screws up the numbering of ordered lists (1, 2, 3…) once you’ve removed a particular list item from the document flow (either by floating or absolute positioning). So you can’t rely on that.

  60. Suppose I want to create two ordered lists, side by side, about President Bush.

    The first list is titled “The Good” and contains 2 items. The second list is titled “The Bad” and contains 44 items.

    You are not going to be able to do this, in order, with your single list solutions.

    Just because Nandini used an UL instead of an OL does not mean that some people are not interested in the 2 list solution.

    I have been looking for a way to do this on my own web site for a while now. I had it working perfectly with absolute positioning…until my brother increased the font size on his computer and my text went flying out of the absolutely positioned div.

    Using relative positioning and flow trickery allows people to use larger text while viewing my site and it still looks like I intended it to.

    Thanks to Nandini and others who posted acceptable solutions to this issue. Thanks to those who posted solutions to the wrong issue (the “this is one list” issue). Some of those posts were very informative, as I use both OL’s and UL’s split into columns.

  61. Kody –
    Your example of “The Good” and “The Bad” might still be considered a single list with two different headings. This is understood as “a list of Bush’s traits.” The more I think about it, the more I disagree that they are two distinct lists.

    You can achieve a list with multiple headings fairly simply using a dl/dt/dd (which per the specs is not limited solely to definitions).

    Nevertheless, the problem described in the main article is definitely a single list problem. As the example illustrates by saying things like “item 1” through “item 4”. It would be different, perhaps, if the problem was “item 1.1” through “item 2.2”, for example.

    Finally, multiple list solutions are nothing new. People have floated elements into “columns” for a very long time. Float the first “column” and give a margin left to the second one. There’s nothing special about lists, really. The only “issue” then is a containing floats problem which has very well documented solutions.

  62. Nandini, I looked at the linked site–it looks really good, but I thought you’d like to know that on the “about us” page, the text in the second paragraph goes past the center background box and spills out over the outer background. I’m using Safari 1.2.4 on OSX. Hope this helps!

  63. This solution is really great for a fixed number of bullets. What if your data is pulled in dynamically and you want the items to run in a columnar fashion? For example: a list of birthdays for a particular month that are ordered by day, top-to-bottom. How could these lists get rendered semi-evenly across 3 columns (or so) using CSS?

  64. Not sure how this got published. 1. This would be cool if the it was all in one list with no special classes for left/right 2. Paragraph spacing issue should be fixed by just setting the default padding/margins for paragraphs. 3. More reasons…
    I expect more.

  65. My apologies to the author, but this has got to be one of the least informative articles ever to grace the front of alistapart. I know they’re hurting for content, but… geesh.

    anyhow, i took 5 minutes to take the authors approach and create a clean, completely unclassed page that accomplishes everything the author intended. I eliminated floating the

      ‘s left and right, and am floating them both to the left. I assigned clear:both to the

      tags to prevent them from creeping upward at all. I used PIE’s float-clearing trick to make sure my div wrapped the entire setup.

      It’s as close to 100% semantic as we can get with CSS2.

      http://www.reaxion.org/listapart.html

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA