Thursday, March 9th, 2006

Eliminating redisplay flashes in JavaScript

Category: Articles, JavaScript, Tip

Patrick Fitzgerald has written up his technique for eliminating redisplay flashes in JavaScript.

We all see this problem in various scenarios. Nice semantic HTML comes down before the CSS/JS has styled it. For a split second you see the ugly style before the true style is applied.

Your first thought might be “I’ll just add a style to the content to make it hidden (CSS display:none), then my JavaScript will run and reveal it!�? But that puts a big crack in our Holy Grail, because if you use CSS to hide the content, it will not be visible to users who do not have JavaScript.

Here’s the method I used:

  • Add a class javascript-hide-me to the content you need to hide, but do not define that class in your CSS.
  • Before the content, use JavaScript to define the CSS class. The easiest way to this is by using document.write in the head section of the page, but purists might want to directly modify the DOM.
  • After the content has been transformed, use JavaScript to remove the CSS class and reveal the content.

Posted by Dion Almaer at 11:13 am
10 Comments

+++--
3.4 rating from 22 votes

10 Comments »

Comments feed TrackBack URI

Instead of using document.write to add the CSS, I would have taken it a little bit further… and of course, used the DOM.

js = document.createElement('style');
js.appendChild(document.createTextNode('.javascript-hide-me{display:none;}'));
js.type = 'text/css';
document.getElementsByTagName('head').item(0).appendChild(js);

-Ryan

Comment by Ryan Brooks — March 9, 2006

I handled this issue in a similar way … I added “display:none” to the style of the “tabber div” to hide it during the manipulation, then used prototypes Element.show() to display it when done.

Comment by Neville Burnell — March 9, 2006

(oops, hit submit too soon … to continue)

So this post helps because my approach doesnt handle the “javascript disabled” problem – thanks.

Comment by Neville Burnell — March 9, 2006

Maybe this will come in handy: http://www.bobbyvandersluis.com/articles/dynamicCSS.php

Comment by bobby — March 9, 2006

Bobby’s is very well thought-out, but I prefer the simplicity of Patrick’s technique, especially because you don’t have to load a whole library of functions that slows page loading even more! XHTML and serving as XML is overrated anyway IMO.

I would only add a check for DOM compatibility before document.write-ing in the STYLE block: if (typeof document.getElementsByTagName != "undefined") {document.write...}

Comment by Stephen Clay — March 9, 2006

@bobby and Stephen: thanks for the comments – I have added your information and links to my original post.

Comment by Patrick Fitzgerald — March 9, 2006

How about creating an external stylesheet that defines .javascript-hide-me { display:none; }, but link to it as an alternate stylesheet so it won’t be applied by default.

Then use JavaScript to change it from “alternate stylesheet” to “stylesheet”, so it will be applied.

I tried it here and it works in Firefox and IE6 on Windows.

Comment by Patrick Fitzgerald — March 9, 2006

Regarding the “alternate stylesheet” method, it’s unreliable since the browser loads the external stylesheet.

Another technique I tried is to hide the content, but then use a NOSCRIPT element to display it. Unfortunately NOSCRIPT cannot be used in the HEAD element, so it’s not valid code, but it does work.

Comment by Patrick Fitzgerald — March 11, 2006

I’ve used something similar in the past, except hiding the entire page instead of a specific class. For example, my Borders demo, http://verens.com/demos/borders/test.html, redraws the borders of classes where the CSS demands curves. To reduce flicker, the script hides the entire page upon activation (see in the init() function), then shows the page when it is complete.

Comment by Kae Verens — March 12, 2006

[…] Welcome, Ajaxians! […]

Pingback by BarelyBlogging » Blog Archive » Eliminating redisplay flashes in JavaScript — March 13, 2006

Leave a comment

You must be logged in to post a comment.