Let Them Eat Cake

by Aaron Gustafson

85 Reader Comments

Back to the Article
  1. People have raised some problems with this
    – bookmarking / open in new window
    – javascriptless paupers (although that wasn’t strictly valid)
    – it’s a bad thing to reimplement browser features

    Set up your links like so.  The #link is for a non-js user / bookmarking, and the onclick is for the dynamic functionality.  return false means that the link gets ignored, which perhaps makes things less confusing.

    <a href=”#section”  return false”>section</ah>

    On page load, check for #section (regexp on location.href), and if so, called show(‘section’).

    That way
    – someone can bookmark the link, or open it in a new tab/window and it will save to #section

    – for javascript users, the #section links will do what you want them to: link to the the subpage, rather than scrolling to the appropriate section of the page.
    – non javascript users will get a menu of # links menu, which is a nice alternative.

    Also, from a philosophical viewpoint, the set up is a little closer to a restyling of the # link functionality, rather than a rebuilding of existing browser features.

    Copy & paste the code below to embed this comment.
  2. What if you had a way to check what section is shown, so you can add a URL query (like cake.html?section=info). My script allows you to come to the cake at a certain section, but it doesn’t solve the bookmark problem.

    Copy & paste the code below to embed this comment.
  3. For everyone griping about how a “page” is the chunk – what are paragraphs then? – all you need is a “show all” link.

    They way I’ve done the same is to take all headers on a page and restyle them into tabs (a link bar looks like site sections) at the top along with a “show all” link. The method above takes care of bookmarks. Event handlers do the rest.

    Voila: no need for scrolling and an effective method for immediately seeing what’s on a page – useability! – and choosing the sections you want to read (particularly good for discrete sections such as reviews, or model info). Not always the best method, but a great one sometimes.

    Dante: your page doesn’t work in my Firefox.
    Error: missing variable name
    var goto = text.substring(location.href.indexOf(”=”)+1,location.length);

    Copy & paste the code below to embed this comment.
  4. ‘No one else found it funny that Aaron used the text-shadow property when no browser supports it yet?’

    Heh :)  But you were right about Safari; it does support text-shadow from 1.1.

    Copy & paste the code below to embed this comment.
  5. One of the better articles I’ve read in a while, an interesting idea with loads of potential :)

    (btw: a.href should be a.getAttribute(‘href’))

    Copy & paste the code below to embed this comment.
  6. http://squidfingers.com/code/dhtml/?id=scrollwin

    Copy & paste the code below to embed this comment.
  7. I implemented Sam’s idea for anyone interested. Sam’s post is at http://alistapart.com/discuss/eatcake/5/#c7784

    Advantages:
    1) Opening links in new window works
    2) Bookmarking a section works

    Disadvantages:
    1) Re-implementing browser features
    2) Forward/Back buttons don’t work

    Here it is (Only tested in mozilla):
    http://www.csl.mtu.edu/~eslathro/ala/cake.html

    Copy & paste the code below to embed this comment.
  8. Safari 1.2 has the best CSS3 support of all modern browsers. I was completely suprised. Thanks for compatibility info. See my compatibility table: http://geocities.com/seanmhall2003/css3/compat.html

    By the way PPK published a new article about JS articles on ALA: http://www.quirksmode.org/oddsandends/ala_javascript.html

    Copy & paste the code below to embed this comment.
  9. I know it doesn’t work in Firefox. Only IE 6 gets it right. I could get it to work in Firefox, but then you couldn’t enter at a specific section (like ?section=bake).

    Copy & paste the code below to embed this comment.
  10. regardless of it’s usefulness, that script reads like English.

    gorgeous.

    Copy & paste the code below to embed this comment.
  11. I was wondering if there was any easy modification that could be done to the script to make it just toggle the div clicked on from display:none to display block back and forth instead of just showing the one clicked on and collapsing all others?  Sorry my scriping is horrible. 

    I’m making a program that will ideally generate a html list of the files on a person’s hard drive in a directory tree.  when you click on a node of the tree, it will reveal the files in that node and their file information in a table.  If you click on a child node with this kind of script, it will collapse the parent div when hidedivs is called.

    All of the other scripts i’ve been able to find for toggling don’t include a function to collapse all nodes on page load, so i was trying to use this one for cross platform compatability without having to put inline display:“none” everywehre.

    Copy & paste the code below to embed this comment.
  12. Everything seems to be very smart but pressing the back button to get back to the previos section (Introduction, Ingredients…) you “jump” back to ALA site.
    The document behaves in an unexpected way, this could create confusion and disapoint among users (the same it happes with Flash sites)

    Copy & paste the code below to embed this comment.
  13. Speaking of usability and accessibility, wouldn’t a good practice be titling one’s articles with something a bit more descriptive than “Let Them Eat Cake,” especially when said article titles appear in syndicated RSS feeds?

    Copy & paste the code below to embed this comment.
  14. Earlier in the discussion, Dante-Cubed introduced a link to his DOM-based AccessKeys method, as a better example of adding accessibility and usability. Is this to suggest that AccessKeys isnt as useless for accessibility as I’d beleived until now for the reasons decribed at http://www.wats.ca/articles/accesskeys/19 ? “So while it seems that Accesskeys is a great idea in principle, implementation brings with it the possibility that it either will not be available to all users, or that the keystroke combination encoded within the web page may conflict with a reserved keystroke combination in an adaptive technology or future user agent.”

    Copy & paste the code below to embed this comment.
  15. Nice article. I think I also spotted a Firefox bug while checking out the sample :)
    http://forums.mozillazine.org/viewtopic.php?t=70292

    Copy & paste the code below to embed this comment.
  16. in one hand i agree the arguments about ‘emulating a browser is bad’….and that this trick is only good for cool visual affects like collapsing the content of a long article…

    But with all the arguments about ‘if my browser doesn’t support javascript’ all i can say is …. GIVE ME A BREAK!!!!!

    come on, trash your PREHISTORICAL browser and Download a brand new SHINY one.

    Who can be creative without considering the best tools available ….  and i’m not talking about ‘HIGH END GEEK TOOL’…i’m talking about THE WELL KNOW JAVASCRIPT

    a good article … with a bad example… but tools exists just to serve your imagination… if you don’t have imagination…STOP READING THIS BLOG….no?

    Copy & paste the code below to embed this comment.
  17. Hello all,

    I am really amazed and thrilled at the amount of discussion this article has generated. And I am please with all of the comments (even the ones which paint me as out of my mind—perhaps because I’m nearly there). Anyway, just some quick thoughts, responses and background.

    First off, this article is less about the tabbed viewing (in retrospect, perhaps a poor example, but one I figured everyone could easily grasp) and more about the power of using JavaScript only when you know it will be supported. Some people got this right off the bat, others… not so much, but anyway, that was the concept. It was meant to get you thinking, which many of you have.

    Dante-cubed has come back to this again and again with some great ideas, as has Eric L. I really like the idea of implementing a “show all” as stylo suggested. But Vinnie Garcia is right in looking forward toward CSS3 support. Once this is supported, using the :target selector, there would be no need for the inline JS Sam suggested and Eric L implemented. But, being that full CSS3 support is a long way off (at least in the Windows world as IE will now be inextricably tied to the OS), I would recommend taking Sam’s suggestion, but wrapping it in a function which would write out the onclick behavior on the fly (and only if javascript is enabled).

    Anyone who has problems with my JS can feel free to gripe all they want, I am certainly no master. Keep in mind, however that these examples were meant to be readable by everyone (even my wife, who has no clue what I do). Think of it as code on a 4th grade reading level—the USA Today of the JavaScript world. I think using behaviors assigned by JS is great, but wanted this to be very easy to follow.

    As for those of you who found the errant CSS3 text-shadow, that was a wink to the Safari community (which I am not a member of, being PC-based). I realized support for it wasn’t good, but threw it in as a dream (of sorts) that some day browsers would be up on their CSS support.

    Thank you all for reading and keep adding to the discussion. I am really glad you all have taken the time to add your input to the article. I wish all articles existed in this sort of forum.

    Cheers.

    Copy & paste the code below to embed this comment.
  18. I have set up a compatibility table containing up to date CSS3 compatiblity info, and you’d be suprised.

    CSS3 Tests Site: http://geocities.com/seanmhall2003/css3

    CSS3 Compatibility Table: http://geocities.com/seanmhall2003/css3/compat.html

    Safari 1.2 has excellent CSS3 support, and I thank Aaron for acknowledging that fact.

    Those looking for a back button: My rewritten script has one: http://geocities.com/seanmhall2003/SeanSoft/cake.html

    My cake only works perfectly in in (no suprise) Internet Explorer.

    Everyone yells at Microsoft for tying IE7 to the new OS. Apple does the same thing with Safari and everyone…says nothing…??

    Copy & paste the code below to embed this comment.
  19. I really like where you’re going with this, but I have a few improvements I’d like to share with you.  I gave each section an id, and the links of the navigation will change the style of that particular section.  In addition, I’ve modified the onload of the document in case such a hash has been made—you can check it out here http://www.ilstu.edu/~jcpeter/eatcake.html

    Forgive the ugliness of the page, but it’s really just a technical demo anyhow.

    Copy & paste the code below to embed this comment.
  20. It’s ok. I mean, the only thing that bugged me was
    <body >
    This does not seperate behaviour and structure. In the JS file place this at the end:
    window.onload = init;
    Also instead of
    return false
    for the support detect, you can just do
    return;
    The latter is probably safer.

    Copy & paste the code below to embed this comment.
  21. The idea of having all information on a single document and then simulating paged content i.e. only showing parts of the document naturally arise an accessibility question from my part. Imo “accessibility” also covers load time (at least for people on slow connections), and if your document spans over endless paragraphs of text and perhaps a few images you user will be very confused when the page finally loads revealing 4 lines of text.

    Copy & paste the code below to embed this comment.
  22. Right on Anders. I just read through all the comments and was about to say something similar.

    I also agree with the sentiments of a page being a page; this example attempts to simulate the paradigm of multiple pages within what is in fact a single page.

    For me, KISS (keep it simple stupid) still reigns supreme.

    Copy & paste the code below to embed this comment.
  23. I agree with Anders and James.  I’ve used this technique before, and it works well, though as noted it’s a good idea to put real links in the href and add the javascript to an onClick or something. 

    The problem is that this method doesn’t scale well.  Not only is page load time significantly impacted, but what happens when your content changes and you have to add sub-categories.  Then you have to start setting cookies or something to track sub-states, and things start going south quickly. 

    It’s just not a good idea, as it adds a level of complexity that really isn’t necessary.  My 2 cents.

    Copy & paste the code below to embed this comment.
  24. This technique does not improve usability. These two articles explains why:

    J. Ryan Baker (2003) – “… participants using the paging condition took significantly longer to read the passages than either the full or scrolling conditions”:
    (2003)http://psychology.wichita.edu/surl/usabilitynews/51/paging_scrolling.htm

    Jakob Nielsen (1997) – “Scrolling Now Allowed”:
    http://www.useit.com/alertbox/9712a.html

    Copy & paste the code below to embed this comment.
  25. This point is not so much related to the general concept of the article but to the tendency for the centered fixed page to jump/reposition itself when it increases in length and needs to be scrolled – I find this an unattractive feature of the site. The ALA pages are always longer than the browser so this does not happen.(IE has scroll bars permanently positioned). 

    Is there a simple script to enforce scroll bars in Mozilla even when they are not needed so that when they are needed the page does not jump?

    I love ALA but am a beginner!

    Copy & paste the code below to embed this comment.
  26. I’ve never found a good way to do that in javascript (i thought I had to tie onload to the document object, which never worked for me).  I totally agree with you that the more seperation you can get, the better.  Anything that minimizes the risk of not being able to use the page is good in my book.

    Copy & paste the code below to embed this comment.
  27. Although I agree with many of you concerning this article’s usefullness and usability in that it may be a stumbling block to some, there are occasions where this approach comes in very handy. I, for one, use almost an identical script to toggle the answers to a list of questions on a FAQ page. It is ideal for a task such as a FAQ page where there is no need to view all at once, and such a page can grow to great lengths. There is also little need for bookmarking of specific sections, or even the need for a back button. However, as a catch-all, at the bottom I do include a tiny section to email the webmaster on any compatibility problems thus ensuring that one always has a way of getting the information they need. g

    Copy & paste the code below to embed this comment.
  28. An excellent article on DOM and JavaScript, but not so good for accessibility. As was pointed out earlier, modern tools like JAWS won’t handle a page like this properly. The first rule of achieving true accessibility: keep it simple. (That doesn’t mean keep it DUMB.)

    I do think this code snippet would be excellent, however, for publishing. I used to post multi-page articles all the time, to minimize scrolling, but the process of rewriting one long page when I was done into several smaller pages took a lot of time and led to clumsy mistakes. A script such as this would allow me to post as long a page as I want, and have it automatically be broken up into chunks (I’d still have to add the div’s, but that’s easy.) Fortunately, my articles are never so long that download time would be an issue, although one should bear that in mind as a disadvantage to this approach if you are serving to a broader user base that isn’t necessary broadband-saavy. Two improvements I would make: first, a “Next” link at the bottom of the page to go to the next div without having to go back to the top (too much eye scanning), and maybe “Prev” button to replace the lost “Back” functionality. Second, a link to “Show All” that would display the entire page at once, for those who LIKE to scroll, or want to use full-page text search.

    What I found most interesting in this article, though, was what you didn’t discuss and what other people have been wondering about. I, too, wondered why you didn’t use onClick handlers instead of rewriting the links with fixLinks(), until I tried it, and realized that the Back button failed to redraw the correct div (even with an onLoad handler, it fails in Mozilla). I also wondered why you were rewriting the div’s to use the .hidden class, when you could have just had a class defined for every div, but separate definitions for screen/print media. Then I realized that order of precedence broke that idea, too.

    These would have been excellent additions to the article. Many times, knowing why a more “obvious” solution doesn’t work is just as instructive, if not more so, than the solution that does. But thankfully, that’s why we have the discussion board on ALA—looking past the flamage, most of this was discussed here. Even my suggested improvements. Gotta love it.

    Copy & paste the code below to embed this comment.
  29. i’m no programmer but is this what you were thinking of?
    http://www.dentynefireandice.com/promos/lunch/

    remember don’t rip the programming, still learning. I still think the article is a good idea if used on small portions of content, not entire pages.

    Copy & paste the code below to embed this comment.
  30. I found a seemingly perfect script for what I wanted in this thread http://forums.devshed.com/t77556/s.html

    The opening script tag is malformed, but the rest of the script works perfect in every browser i’ve tried it in and it leaves the content accessable to people who do not have javascript enabled / working properly.  I had to remove one line from the script (the //contractcontent(cid) line in the expandcontent section) but otherwise it works out of the box.

    Thanks for the sample reply.  I will study it for future reference.

    Copy & paste the code below to embed this comment.
  31. Peter-Paul Koch published an article about separating javascript (behaviour) from the structure of a HTML page. I guess he makes explicit what this article is hinting at with the javascript rewrites:

    http://www.digital-web.com/columns/keepitsimple/separating_behavior_and_structure.shtml

    Copy & paste the code below to embed this comment.
  32. You make it look like the information is devided into multiple pages. A search engine bot will see it as one page and may take some sentences of the content on their search results page. The visitor will get frustrated when the shown part is not found immediatly at the devided page..

    Copy & paste the code below to embed this comment.
  33. http://www.elegantdesign.co.nz/blog/?postid=8

    This article may be of interest to some of you.

    Copy & paste the code below to embed this comment.
  34. There’s a significant issue with taking this approach for people with [removed] as the page loads all the content is displayed, and when it finally loads content disappears! Where’s it gone? What’s happened? I didn’t do anything to ask the content to disappear?

    This is a severe usability issue, especially for those using pages over slower connections (as I am now).

    Gabe

    Copy & paste the code below to embed this comment.
  35. i’ve used this with a tabbed list and replaced divs with fieldsets. this is within a CMS interface where theres no need to bookmark or print the sections. being able to break up forms makes a huge difference as these can often be overwhelmingly long.

    Copy & paste the code below to embed this comment.
  36. i’ve implemented the technique in this article on gmail, something of a proof of concept for the article’s example. readers have commented that the page is “much much better and easier to read than most online articles.” so i think this sort of tabbed navigation (especially given the fact that it is also usable without javascript) is very usable.

    the article:
    http://vault.silversand.org/pages/gmail_beta.php

    Copy & paste the code below to embed this comment.
  37. The footer text in the finished example is unreadbly small in Opera 7.

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

    being a bit slow, I’m writing this after the rush of messages in this discussion. Thanks for an interesting article, but as some already have pointed out, there are somethings that could be done differently.

    As I see it, rewriting the URLs is unnecessary. Use event attributes instead:

    <a id=“navIntro” href=”#intro” >

    and this would work just fine with or without javascript, rendering the FixLinks-function unnecessary.

    Copy & paste the code below to embed this comment.
  39. from
    http://www.alistapart.com/d/eatcake/1.html

    Line: 2
    Character: 1
    Error: Syntax error

    w00t

    Copy & paste the code below to embed this comment.
  40. On browsing through this article I got the impression that it would eliminate scrolling. On viewing the finished thing I still had to scroll to read all the text (1280 × 1024 res). So I don’t quite get the point of the script – brilliant as it may be.

    There’s nothing wrong with scrolling, as long as you are either interested in the article or know what you are scrolling too. It’s certainly far better than clicking ‘next’ buttons all the time. I sometimes get the impression that breaking text into chunks has ultimately only one purpose – pushing more adverts at you!

    Copy & paste the code below to embed this comment.
  41. Regarding cocerns for users with slow access, when I use dial-up, I opening several pages in various windows so I can be loading one while reading another.  This technique does this automatically.

    Unlimited local calling is relatively rare outside the US so slow speed users are usually concerned about the total time online.  I love this technique for it’s potential for entire sites to be viewed offline easily. 

    But the designer would have to find a way to let users know that the entire site is loaded and can be viewed offline.

    Copy & paste the code below to embed this comment.
  42. This is something I searched for. Thanks

    Copy & paste the code below to embed this comment.
  43. I know I’m coming in three months late here, but if anyone’s still tracking the thread, I wonder that no one has noted (and provided the, perhaps, super clever solution which escapes me still) the quick flash-of-text you get in many browsers when deploying this technique.

    Sure, it’s just all the IEs and definitely a by-product of bandwidth, but it happens even to a relatively meager 20K glossary (for instance).  The javascript can’t go to work until the document loads, which means that the body of the text flashes quickly before your eyes before it’s mostly rewritten to “display: none”.

    This flash is esthetically unacceptable.  The “obvious” solution (set to “display: none” in CSS and wait for the javascript to display the first element, or whatever) is also unacceptable as anyone with CSS capabilities and disabled javascript won’t see a thing.

    Am I missing something or is there a workaround for that?

    —H

    Copy & paste the code below to embed this comment.
  44. In response to Heidi’s question, as this script relies on an onload event, that is why you see the flash. The only solution I can think of off-hand would be hiding the whole page until the whole thing is loaded and revealing it all in the onload event. To make this work with JS on or off, I would write some JS in the head which wraps an if document.getElementById() around a [removed] JS line which writes a css rule stating “body {display: none}” or something similar to hide the page. You could then add a JS function to the onload event to undo this.

    Again, this is purely hypothetical, I have not tried it out for sure, but in theory it should work.

    Copy & paste the code below to embed this comment.
  45. I have tried to improve this script, but the new widget still has some bugs.
    Please look at it.
    Thanks.

    Lorenzo De Tomasi

    Copy & paste the code below to embed this comment.