Handling JavaScript-disabled Browsers

Tweet

The following is republished from the Tech Times #159.

Previously, I mentioned that you should consider three main groups of people when adding JavaScript to your site—users without JavaScript capabilities, users without a mouse, and users of screen readers—and that supporting each of these three groups becomes progressively more difficult. In this post, we’ll focus on the first group, and discover how very easy it is to accommodate them with the right approach.

In the introductory JavaScript book I’m currently co-writing, one of the first big examples is an accordion control. This user interface element collapses a series of content blocks so that only their headings are visible, and then allows the user to expand the blocks one at a time by clicking on the headings.

This is a great example of how the right approach can accommodate users without JavaScript support (or with JavaScript disabled) with no extra work.

It can be tempting to write the CSS code of your page so as to collapse the blocks of the accordion control, and then write JavaScript code that will expand the blocks on cue. But disable the JavaScript, and users are left with the collapsed blocks and no way to read them!

In the past, conventional wisdom advocated an approach called graceful degradation, which would involve adding extra “fallback” code for users or browsers that were not able to handle the fancier bits of your page.

The graceful degradation approach to the accordion problem, for example, might be to put an expanded version of the accordion’s content between <noscript>...</noscript> tags, so that browsers without JavaScript enabled would display the expanded content. This is extra work, and is the sort of thing that really sours developers on accessibility.

Today, we understand that this is the wrong approach.

A much better way to solve accessibility issues is through progressive enhancement, where you start by building something that works in the simplest, most accessible environment (in this case, a browser with JavaScript disabled), and then progressively enhance it with features that will improve the user experience in browsers that support them, or silently fail in browsers that don’t.

What this means for our accordion is that we should write the CSS code of the page so that the contents of the accordion are completely visible.

The JavaScript code will then collapse the accordion as soon as it loads, but in browsers with JavaScript disabled the accordion will remain expanded, and the content may be read without difficulty. And there is no need to write any extra code or spend any extra time to achieve this—it’s simply a matter of approach.

Next time, we’ll look at how to make sure this accordion control can be used by people who are either unable to use a mouse, or who simply prefer to navigate by keyboard. This will prove a little more challenging, but is still quite practical in most projects.

If you’d like to read more about graceful degradation and progressive enhancement, I highly recommend SitePoint regular Tommy Olsson’s article on the subject at Accessites.org.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.fruitysolutions.com philwilks

    This is a very common application for me – taking a page and hiding/showing bits depending on what is clicked. I agree that this is definately the right way round to do it, rather than hiding everything via CSS.

    However, my clients often pick up on the fact that the contents of the page flashes up before being hidden by the JavaScript.

    I don’t know of a reliable method for getting round this, but maybe someone else does?

  • warjockey

    well I wouldn’t mind if it flashes for a bit. The above example hides the information so the page is not crowded for the user. So it doesn’t matter if they see it uncollapsed for 1 sec.

  • joan.m

    I’d like to point out that there is a way to avoid that flashing just mentioned. The idea behind the solution is the use of a CSS pseudo class called :target

    With this :target pseudo class you can initially hide all those blocks that must be hidden and on receiving the target event, change the display style to block. Not a single line of scripting necessary, I promise.

    You can visit http://developer.mozilla.org to learn more about this CSS3 pseudo class which still isn’t supported by the ubiquitous IE.

  • http://www.fruitysolutions.com philwilks

    joan.m: That sounds great, but if it’s not supported in IE it’s no use.

  • richm

    philwicks: Saying it’s “no use” is ignoring the huge (and growing) number of us who are not IE sycophants. There ARE other browsers out there.

  • Joan Molina

    richm: I agree with you. In the University where I work all the staff members user Mozilla/Firefox browsers. More than 200 people. I’m sure that the more users choose non IE-browsers the more probable it is that IE adheres to enhanced standards such as CSS3.

  • http://www.fruitysolutions.com philwilks

    Unfortunately my audience is still 75% IE, but it’s shifting quickly.

  • malikyte

    He mentioned the JavaScript DOM processing flash, not the CSS flash. There is a difference. The CSS Flash issue is discussed on the Sitepoint Forums under the Sticky FAQ topic.

    The JavaScript flash problem is discussed here. You may also find this article a bit enlightening.

  • http://www.fruitysolutions.com philwilks

    Cheers malikyte, that’s really helpful.

    The solution to the JavaScript flash is a bit hacky, but is certainly worth the effort if the flash is noticable.

  • rmullins

    good work, i like the idea of ‘progressive enhancement’.

  • http://www.brothercake.com/ brothercake

    Dean’s solution is neat, but it still leaves out browsers that aren’t IE or Firefox/Mozilla (there are more than two browsers ;))

    One other idea is to use a timeout based solution that checks for DOM readiness by testing for the existence of the body element [and any specific elements that are required] — http://www.brothercake.com/site/resources/scripts/domready/

    But personally, I’ve pretty much given up on load-based scripting entirely – I just put <script> includes directly after the elements they affect, and initialise immediately. That way, the needed part of the DOM is guaranteed to exist, and the script initialises as soon as conceivably possible.

  • http://www.sitepoint.com/ Kevin Yank

    Peter Michaux has an excellent, up-to-date treatise on how to get a script to run as early as possible, with maximum browser compatibility.

    It pokes a number of holes in Dean Edwards’s script, and ends up using the DOM polling approach suggested by brothercake above, but with a number of smart optimizations inspired by the Yahoo! UI Library.

  • malikyte

    Thanks a lot, both brothercake and Kevin! Much appreciated!