better unobstrusive javascript element hiding

Many web pages have elements that are only displayed at the users request. Common examples are Facebook's chat tab, Gmail's "more" folders link and Yahoo's dashboard toggles. Typically, these elements are already loaded onto the page, and simply hidden by style sheets. Then when you click on a certain control, a piece of JavaScript un-hides the element.

But what about users who don't have JavaScript enabled? Ideally, you would want to allow them to access the content anyway. Sure, the experience is better with JavaScript, but that's no reason to break it for everyone else. This concept of graceful degradation is known as unobstrusive Javascript.

A typical solution would be to leave the element visible initially via the style sheet, but immediately hide if when the page loads with JavaScript. That way, users with JavaScript can dynamically un-hide it, and users without JavaScript will simply always see it.

The problem with this approach is that it can lead to a flicker effect when the page is first loaded. When JavaScript hides the content while the page is still loading, it may have already been displayed to the user. The user sees the page reconfigure itself, and may interpret this as a problem with the site. Luckily, there is a a better way.

A better way to hide this content dynamically is to output a style sheet dynamically from the HTML HEAD element.

<html xmlns="">
  <title>My Page Title</title>
      // check for WC3 standard DOM compliance
      if (document.getElementById) {
          document.write("<style type=\"text/css\">.hideme { display: none; }</style>");

This will hide any element with the "hideme" class. Because it's executed inside the HEAD tag, it will process before the page itself loads. No flickering. If the user does not have JavaScript, then they will simply see the element.

I'm currently working at NerdWallet, a startup in San Francisco trying to bring clarity to all of life's financial decisions. We're hiring like crazy. Hit me up on Twitter, I would love to talk.

Follow @chase_seibert on Twitter