Don't hate it when the browser displays ugly HTML for a second, then thinks it twice and reformats it as expected?A Flash Of Unstyled Content (from now on FOUC) happens when the browser shows unstyled content before applying the CSS style sheet (wikipedia). It used to be associated to old versions of IE but also with accessible interfaces that offer richer javascript alternatives. Consider the following:
- List menu: the bare HTML should show all options expanded (in case javascript is off, the visitor is a search engine... pick your choice) and use javascript to collapse unselected options.
- Tabs: same thing, show all tab contents and hide the unselected ones.
- Any kind of collapsible interface, Blogger for instance: if the connection is slow you can glimpse the collapsed components while the browser downloads the entire document.
Solutions are not straightforward: components that do not yet exist in the DOM tree cannot be hidden using javascript so they must be created (and maybe displayed) before they can be manipulated.
Register a "DOM document loaded" event handler
An example using prototype:
document.observe("dom:loaded", new function() {
$('myDiv').hide();
});
This waits until the document is fully downloaded and will flash if the page is big enough or the connection crappy enough.
Place a <>script> tag after the element
<div id="myDiv">
...
</div>
<script>
$('myDiv').hide();
</script>
Yikes. You are desperate, right? This script requires that the DOM node already exists, and that sometimes means that the script tag must be placed somewhere else (next to the nearest ending DIV tag, for example). This would not work as a generic approach for a JSP tag (TabTag, MenuTag) that does not know how the surrounding HTML looks like.
CSS sleight-of-hand
Create a CSS style on the fly before the affected HTML content:
<script>
document.write('<style type="text/css">.hide-fouc { display:none; }</style>');
document.observe("dom:loaded", function() {
$$('.hide-fouc').invoke('removeClassName', 'hide-fouc');
});
<script>
<div id="myDiv" class="hide-fouc">
...
<div>
A browser with javascript enabled will not see the component, but javascript-less browsers will. The CSS class is removed after the entire document has been loaded to allow the element to reappear later.
Note that this snippet should be included inside the HTML (not as a external javascript file) and that you should achieve better performance by removing the display:none attribute from the CSS class instead of using a selector, but as said before I am a lazy bastard.
