Complex Dynamic Lists: Your Order Please

by Christian Heilmann

57 Reader Comments

Back to the Article
  1. I really like the idea of using more JavaScript in order to make life easier while still keeping accessibility, even if either JS or CSS are disabled.
    When javascript came up, people used to use it for everything, including important things such as navigations which were unreachable for those having JS disabled. However, soon most of them noticed that they excluded them and therefore they decided to completely set it aside. But now the point is reached where we start to combine the power of JS with the DOM. This makes it possible to view and use pages having JavaScript disabled without causing any problems. But if you have it switched on, it’s more comfortable. And that’s what I really like!

    Copy & paste the code below to embed this comment.
  2. I downloaded the example.zip from the link at the end of the article, but it failed at decompression ( Stuffit 9, OS X 10.3.9 ), with an indication that zipping of the files was not correctly executed.

    Copy & paste the code below to embed this comment.
  3. Progressive enhancement is the way to go. The AJaX problem is really a problem though. It makes me wonder if I should reset values in cookie with each action taken by the user. That way the back/forward could possibly bring them to where they left off, but that could get messy.

    Copy & paste the code below to embed this comment.
  4. Jakob Nielson would have a great deal of negative things to say about such a system. Having so many levels is not usable, especially for partially sighted people.

    Copy & paste the code below to embed this comment.
  5. I sometimes wonder if which audience is more important, the people that navigate without js, groups of visually imparired people or the not so small group of 60%+ that navigate with ie…

    your example has images of arrows are all over the show…  this is definately due to bugs in ie but i think that all solutions should cater for this audience.

    Copy & paste the code below to embed this comment.
  6. A lot of articles, such as this one, discussing Ajax and the use of Javascript for “progressive enhancement” seem to acknowledge “the Ajax problem”, but few seem to offer any ideas as how to overcome the problem.

    Anybody got any bright ideas for implementing the benefits of Ajax without breaking the older, less-cool, but hugely important web controls such as the back button and bookmarking?

    I can’t think of the number of times I’ve hit the Back button whilst using Gmail, only to be spat back to the entry page.

    Copy & paste the code below to embed this comment.
  7. I really dug the article. I may implement something very similar on a site of mine now.

    As for the back button, I picked up an idea from Eric Costello’s Ajax Summit presentation:  Use cookies to store the state.  When the person goes back to the page, it looks at the cookie and gets the necessary data to revert to their current state.  If you were just concerned with knowing which list item was selected, you could possibly pass something in the URL hash.  Something like “#deserts-pancakes-short_stack”.

    Just a thought.

    Copy & paste the code below to embed this comment.
  8. I’m with Alex on this one.  This solution (purportedly) increases accessibility while decreasing usability.  Actually, the point he made about partially sighted people might infringe on the accessibility front as well.  Don’t get me wrong, interesting concept and definitely worth exploring derivatives and other applications, but I just don’t see this being a viable alternative.

    Copy & paste the code below to embed this comment.
  9. This is no triumph for accessibility, either. Using the keyboard, you must tab through all of the links, regardless if they are currently shown or not. A solution to that would need to be found before I would consider implementing this anywhere.

    Copy & paste the code below to embed this comment.
  10. I haven’t been able to toy with AJAX much, but I have had a similar problem with the back button in a WYSIWYG editor we used. When you hit back (before we modded it), everything in the editor was gone.

    The trick was to store the state information in a hidden form element when the onbeforeunload(IE)/onunload(Mozilla) events were raised. When the onload event gets raised, you just pull the state information you stored out and load it. Since onload fires when you hit back/forward and the state information is stored in a form, you can maintain it without using Sessions/Cookies and running into the trouble storing navigational elements in Sessions/Cookies tends to cause (e.g. what if I hit back more than once).

    Again, I’m not absolutely sure the will work in AJAX (or even if it’s a great idea), but it’s probably worth a shot.

    Copy & paste the code below to embed this comment.
  11. There is an assumption here that you can make a menu act like a drop down. The assumption is the reverse of the thinking that a dropdown can be used as a menu. Both are REALLY bad thinking.

    These should not be done as nested lists of links. How would you submit the choice to the server? Use javascript to set a hidden field. Suddenly you don’t have javascript independance.

    The solution is frighteningly simple. It should resolve the accessbility issue and it should resolve the AJAX problem.

    A hierarchical list of Radio Buttons. Now you should be able to use back since the state of the radio button should be preserved. I’ve had issues with onload firing in this situation but that should be resolvable. And it allows you to have defaulted values easily. And it allows you to have more than just the leaf elements selectable.

    Further, using this technique for multiple selections is, IMHO, a usability nightmare. A better solution is a nested list of check boxes that you render as a tree view.

    Finally, if you don’t like seeing the checkboxes and radio buttons, then I think you can get away with using javascript to change the types to hidden. Everything should work honky dory at that point.

    Copy & paste the code below to embed this comment.
  12. You are right if you use the list as a part of a bigger form. However, the final example shows how you send the final option to the server, as a parameter.

    Copy & paste the code below to embed this comment.
  13. Seems like way more clicking than I want to do to eat some Waffles with ice cream. One concept from Edward Tufte comes to my mind when seeing this example:

    Comparison between groups is not possible. Sure, I can see where I’ve been (Desserts [misspelled in the examples], Waffles), but I wouldn’t mind seeing what kind of burgers are available at the same time as what fries to pick. Maybe I’d like to pick some fruit to go well with a drink, but without seeing those items next to each other, I have to flip around a lot between categories (more clicking!!).

    “High density is good: the human eye/brain can select, filter, edit, group, structure, highlight, focus, blend, outline, cluster, itemize, winnow, sort, abstract, smooth, isolate, idealize, summarize, etc. Give people the data so they can exercise their full powers—don’t limit them.”

    I feel like I’m using some poorly designed social networking website with 10 clicks and a few page reloads to accomplish anything. I get irritated and annoyed quickly and want to leave. Surely there are better ways.

    Copy & paste the code below to embed this comment.
  14. The article did what I wanted it to do: It made people think about those two :)

    • Keyboard Access:
      It is true that keyboard access is bad, and I don’t know a way around that. The only option would be to check for onkeyup and set the focus on the next link on the same level when enter was not pressed. However, this might interfere with the keyboard settings of assistive technology.
      Another option would be to check if a mouse is in use. I toyed with the idea of checking onmousemove on the body as an indicator. Anyone interested in doing some tests?

    This is a common problem with nested lists, how come it doesn’t crop up when the talk is about fading in CSS only multi level dropdown lists? :-)

    • Horizontal alignment bad for sight impaired users:
      Again true, but is there a better solution?
      We could collapse the parent level to a smaller area, or just order the whole screen differently. The other option is to offer both ways of choosing your meal: A step by step reload for a smaller screen, or this high level choice. The data could be generated by the same server side script.
      The only way to accommodate every user is to offer her a chance to customise to her needs.
    • 60% of the Users on IE
      I presume you mean the dead IE/Mac? There is a style sheet, it can be changed. As I don’t own a Mac I cannot predict every error of it.

    And finally, Usability is not Nielsen, Usability is dependent on the audience and the users of the product. There is no silver bullet.

    Copy & paste the code below to embed this comment.
  15. Enhance the script to offer a link stating “show me all options”. Problem solved.

    Copy & paste the code below to embed this comment.
  16. How is a link offering “show me all options” any better than just the whole original list with no styles?

    Don’t get me wrong, I think it’s a cool technology concept and degrades well, but I am just questioning how a user would feel about all that clicking. I know I hate those three drop down boxes at car websites: New/Used, Year, Brand, Model. Refresh. Refresh. Refresh.

    Copy & paste the code below to embed this comment.
  17. It makes sense, but honestly if your code is lean a page refresh is not going to break the www. I like the ideas but the end result is disparagingly ugly.

    Copy & paste the code below to embed this comment.
  18. I think you ideas are great. There needs to be some more time spent on such a system if it were to be used. Also, this would not be good for a majority of cases, only some of them.

    Thanx for the article.

    Copy & paste the code below to embed this comment.
  19. I don’t understand why the “off-left” technique is used here.  How about display:none instead?

    .domenabled ul#finder ul.hidden
    {
    display:none;
    }
    .domenabled ul#finder ul.shown
    {
    display:block;
          top:0px;
    left:200px;
    position:absolute;
    }

    That way the invisible links aren’t part of the tab order anymore.

    As I understand it, the point of the Rundle’s technique is that screen readers will read text when it is invisible, so that image replaced text will still be read by screen readers.  In this case, I don’t think you want a screen reader to read text that has been rendered invisible, right?

    Copy & paste the code below to embed this comment.
  20. Some screen readers don’t read the hidden text, others do, so it is not failsafe sadly enough.

    Copy & paste the code below to embed this comment.
  21. I predict that one of two users will have problems dealing with that menu. And we need more tested solutions at ALA.

    Copy & paste the code below to embed this comment.
  22. Those people seem to have a solution for the back button : http://dojotoolkit.org/

    This article discusses this :

    http://dojotoolkit.org/intro_to_dojo_io.html

    Copy & paste the code below to embed this comment.
  23. During the last Usability testing I conducted a lot of Users kept pressing the back button on a Flash only site. For me that meant the Flash application was not obvious and maybe a bad solution in this context.

    Should I claim now that in every situation and for every project a pure flash site is bad or is usability also dependent on who you expect to reach?
    I never claimed this is the solution to end all solutions, it is something to consider. The safest way is still a step by step order with reloads in between.

    I dont know how ALA would ensure “tested solutions”, can you elaborate?

    Copy & paste the code below to embed this comment.
  24. I like it very much. Just one comment though: under Fries, you forgot Poutine, a French-Canadian delicacy of hot fries covered with white cheese curds and then a heaping layer of gravy, mmmmm, good for the heart.

    Copy & paste the code below to embed this comment.
  25. I’ve been thinking about the state/back button and bookmark problem for a while. Could you not do something as simple as:

    1) Check for session variable. If the session contains a “state” reference ID, load the page with the with a hash reference of the state variable: i.e. mypage.php#9999-9999-9999-9999

    2) If there is no state reference ID, create a new one. This involves creating a new entry in a database table called “state” which will use the state reference ID as the primary key.

    3) For every message that is SENT to the server side, store the message content.

    4) If the user visits the page via a bookmark or URL pasted into the address bar, check the database for the state reference ID, pull out the messages and run them again to rebuild the state of the page.

    All you need to do then is store the last message sent for each updated section of the page (ie. if you have a table containing a list of records, only store the message that was sent to retrieve that list), and then “action replay” the message to get the state back. This would work for the back button/forward button too… (just replay the messages).

    Doing it this way would mean that all the state control stuff would be server side: you would just need to run a function onLoad that checks the database for a state reference ID: if it exists, re-run the message used to generate that state…

    Copy & paste the code below to embed this comment.
  26. oops, forgot to add: the reason for the session stuff is to allow only the session owner to make changes to the page state: “viewers” of the page state would see the page in its last updated form. The viewers ofthe page would be able to change the state, but doing so would give it a new state reference ID….

    Hmmmmm… thinking about it… the state reference table could get very big very quickly if you had a popular “state” page…..

    Copy & paste the code below to embed this comment.
  27. Thanks for the link Christian, I’m glad that people can adapt negative indents or placement to fit their own needs.

    The article was great, thanks for the write-up!

    Copy & paste the code below to embed this comment.
  28. Ben, you’ve proposed a nice solution but I can see that this may have problems scaling for larger sites.

    If you’re going to use a database to record every change in state and then query this every time a page is loaded you’re going to see your database getting out of control very quickly, not to mention that additional overhead that this will add to the loading of your pages.

    Copy & paste the code below to embed this comment.
  29. Yeah… I figured that the DB would get very big very quickly.

    I like the idea of storing the messages sent to create the state of the page, and using the reference to track that state, but it also leads to another problem: how long do you store a “state”? Ideally, it would be for ever.

    Binding the state to the browser (using cookies for example) would let you send the URL to other people either, so thats out of the question.

    One to ponder..

    Copy & paste the code below to embed this comment.
  30. I found a error in your article (not related to your dynamic list).
    you say:
    [snip]Unless we generate the arrays of the script on the server (by setting a text/javascript header in a PHP script for example) or write them out inline, we have to maintain the data in two locations.[/spin]

    I once did make dynamic js with header set to text/javascript and it made IE6 Win98 crash in combination with window.open fore some strange reason.

    One SHOULD set the header to application/x-javascript which is the correct MIME-type. I hope this will help some people.

    Copy & paste the code below to embed this comment.
  31. I like the idea behind this and it might spark some no methods, but the final example takes to much vertical space to use. Which is one of the reason to use a drop down box (select tag).

    A better method is to use the optgroup tag. This way each group of options can be divided nicely in one drop down box.

    If you have sub groups you can use CSS or   entity to add an ident levels. I used   since IE will not let you use CSS to modify the contents of select tag.

    Copy & paste the code below to embed this comment.
  32. Optgroups are a wonderful way to sort a select into different categories, but it doesn’t really indicate a relationship between them and you cannot nest them, or am I wrong there?

    W3c:
    The OPTGROUP element allows authors to group choices logically. This is particularly helpful when the user must choose from a long list of options; groups of related choices are easier to grasp and remember than a single long list of options. In HTML 4, all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested).

    As for nbsp, that is a bit oldschool and really is mixing content with presentation- painting with text.

    Copy & paste the code below to embed this comment.
  33. If you define an off-left (or off-top) shift in pixels, then resize text to be extremely large, the text can intrude on the visible page unless carefully constrained.  I’ve found it more foolproof to set the left margin of hidden text in ems so that its off-screen offset increases directly with the font size.

    Nice article, Chris.  Although, in the face of this bramble of accessibility & usability issues, my approach has been to keep a page quite lean to get immediate response time reloading it with new values.  Most of the CSS you’re using here could still apply just fine if each menu level were supplied by the server.

    Since you’re using JavaScript, why don’t you store unused portions of the menu system in hidden elements and then copy them to create new DOM nodes to produce submenus on demand?  Or does that strategy have as many thorns for screen-readers as trying to unhide hidden elements?

    Copy & paste the code below to embed this comment.
  34. I like the hierarchical presentaion of information: I am not a web designer, and so do not know the gui issues well. But I am interested in the use of wizards to program code or at least do some kind of code generation.
    BTW, whats wrong with a page submit to send the results to the server? And what about this XMLHttpRequest object I keep hearing about? There is a technique to use a submit from an invisible (1 pixel) frame to transfer data without a page change.
    These techniques get a bit confusing to a server programmer drilled in the ideology of MVC.
    JB

    Copy & paste the code below to embed this comment.
  35. I really like the idea of dynamic web content and I’m trying to utilise as much of it as I can in the slow process of redesigning my web site in my free time. One thing I thought would be nice was dynamic menus and after finding several possibilities I thought I’d look to some of my favorite CSS-oriented sites. Lo and behold I found this. It’s a cool idea, but I was wondering if it’d be possible to implement it differently.

    I’d like to have links that are displayed across a top box (ah, the multi-box stereotypical layout…) change a menu in a left box when clicked or rolled over (either way is fine). So if one link is Home then it’d change the left box to have all the links for the home section. If one top link is Comics then the links in the left box might display stuff like Top Sellers, Recommended Reading, New This Week, etc.

    I don’t know javaScript and I’m still learning PHP. The example, though, seems to load everything to the right.

    Also, what’s this about tabbing through the links? Does that mean all the links are already there and they just have to be displayed, so a user could tab through the ones they can’t even see yet?!

    Copy & paste the code below to embed this comment.
  36. There’s no vegetarian option for main courses :)

    Copy & paste the code below to embed this comment.
  37. This example: http://www.alistapart.com/d/complexdynamiclists/order.html was just facinating. I understand the usability/accessibility issues but it is just the navigation I have being struggling to think about. One that suggests journey or progression from one place to another in a horizontal form rather than vertically as most menus do. Thanks for the great pointer and all credit due.

    Copy & paste the code below to embed this comment.
  38. Hi Christian,

    I love your article and solution. It works well in the majority of browsers my visitors use and degrades well if javascript is turned off.

    I’m trying to use it in a situation where I have two lists and I want my visitors to easily tab back and forth between the two lists. I almost have it working except I’d like to have the first list open by default – without the user having to click on the first tab – is that possible to do with your code and what would I need to change?

    Many thanks for a great solution!

    Copy & paste the code below to embed this comment.
  39. shouldn’t be hard to do, I will look into it after the bank holiday. There is sun outside here in London, and that is an occassion far too seldom to let go away unused.

    Copy & paste the code below to embed this comment.
  40. This is a great example. But there is one piece of functionality I would like to have the parents (Main Courses, Drinks, Salads, Deserts in the example) be links (targeted to another frame). When I make them links they become null. It would be great to have another frame display all of the deserts when you click it and also have desert act as a parent and expand to show the desert categories. Is this possible without radically altering the code?

    Copy & paste the code below to embed this comment.
  41. It is possible, but how would you expand the children? This would make you dependent on a mouse again.

    Copy & paste the code below to embed this comment.
  42. I would like to put this in a box (e.g. border around the content), but I cannot get the box to contain the nested lists. In the posted examples, the size of the content area is fixed,so it is a non-issue. I thought that once the absolutely positioned inner boxes were nested inside a relatively positioned box, then the external box would grow to hold vertically to accomodate the the content, but for whatever reason, I can either show the entire list of nested lists and it fits in the box, or I can use the javascript to hide/show elements, but everything after the top level is outside the box.

    Any examples of how I could get this working would be greatly appreciated.

    Copy & paste the code below to embed this comment.
  43. Hello Mr. Niggel

    This is my first time posting… Please don’t be offended.

    I don’t know much about JavaScript, but is it possible to solve the tabbing problem by using tabindex attribute?  And could this tab attribute be changed dynamically using JavaScript?

    Copy & paste the code below to embed this comment.
  44. I just posted a new technique on my website to create accessible dynamic select boxes without arrays, using unobtrusive JavaScript and progressive enhancement: http://www.bobbyvandersluis.com/articles/unobtrusivedynamicselect.php

    This technique will probably change the perspective on the complex solution as described in this article. However, the real question will probably be how usable (or suitable) dynamic select boxes are as navigation tools.

    From that point of view I like the solution Chris offers, because it is based on existing popular navigation interfaces and it visualizes how you navigate through a hierarchy.

    Copy & paste the code below to embed this comment.
  45. Dessert, not ‘desert.’ I always remember “two s’s” because I want more dessert.

    Copy & paste the code below to embed this comment.
  46. Very nice article, thank you very much.

    Copy & paste the code below to embed this comment.
  47. Apple has a variation on this kind of column list on their site, styled to look similar to the columns in the Mac OS X Finder;

    http://www.apple.com/downloads/dashboard/

    Copy & paste the code below to embed this comment.
  48. Very useful function made here.

    Copy & paste the code below to embed this comment.
  49. The Widget Browser on the Apple site should be marked up as a table instead of a collection of unordered lists. There are clearly three columns – not just visually, but logically! – namely Category, Widget and Info.
    Set up as a table, it would also degrade much better for people without CSS or JavaScript. Let’s see if I can cook up an example.

    Copy & paste the code below to embed this comment.
  50. Hm, I grocely underestimated the trouble with relocating tablecells through CSS, due to lack of hierarchical nesting in tables. Ah well.. here’s how far I came, if anyone wants to finish it.

    Copy & paste the code below to embed this comment.
  51. Very incredible script but a big “default” : if you have 100 or 150 possible lists with a graphic (normal.gif), it loads the 100 / 150 normal.gif each time you click. The only solution I have found is to not put pics.

    Copy & paste the code below to embed this comment.
  52. thanks alot!

    Copy & paste the code below to embed this comment.
  53. It becomes easy to criticize a script and throw problems at it like “what about the ajax problem?” – “what about when js and css is disabled?” – “what about screen readers?”

    Sheesh. I can see why ALA initiated the ‘experimentation – use with caution’ warnings from a while back.

    However, I will agree on the asthetics of it. It does look a bit awkardly ugly. But what’s really at stake here is the functionality. ALA has never claimed to be awesome designers, but this is a killer script (killer being a good thing).

    Most likely, these are the kinds of widgets that I would implement on my own site. It would take weeks of meetings to get something like this implemented on a real project.

    Copy & paste the code below to embed this comment.
  54. I was and am still very much interested in your method of display and choosing options. However,  like some others thoughts – while it appears to be an excellent script technically, the aesthetics does baffle me slightly. I wonder how easy it is to make it into a vertical menu, (rather like the navigation menu for http://www.saila.com/usage/layouts/ ) while still retaining its accessibility? :) thanks!

    Copy & paste the code below to embed this comment.
  55. Thank You, Christian!
    This is very interesting and comfortable solution! And understandable examples.

    Copy & paste the code below to embed this comment.
  56. common when is the next update?

    Copy & paste the code below to embed this comment.
  57. What

    REALLY

    I can use HTML. Here’s the code I wrote for my page:

      <h2>This is an H2 headline</h2>


    I’m so glad HTML is blocked.

    Oops. It isn’t.

     

    Copy & paste the code below to embed this comment.