16 February 2009

Changing style regarding changing style

I was having a conversation with the esteemed Mr Alexander today about changing CSS styles based on whether JavaScript is enabled in the users browser.

This problem had consumed some of my thoughts in the past and eventually I chose to use the technique I termed progressive degradation, something I have blogged about in a previous post.

Progressive degradation involves writing your CSS with the assumption that JavaScript is enabled. You then include an additional style sheet in this way:

<noscript>

    <link rel="stylesheet" href="noscript.css" type="text/css" media="screen" />

</noscript>



This has generally worked well for me with the one caveat that this is invalid HTML. This has concerned me a little. The argument which both myself and Mr Alexander have used is that this is easily the simplest way to adjust styles depending on whether JavaScript is enabled or not.

I prefer to write my CSS with the assumption that the best possible experience is available and then include CSS to enhance the experience for those users with a less capable user agent as required.

Mr Alexander proposed another potentially neat solution:

<link rel="stylesheet" href="noscript.css" type="text/css" media="screen" id="noScriptCSS" />

<script type="text/javascript">

    var noScriptCSS = document.getElementById("noScriptCSS");

    noScriptCSS.parentNode.removeChild(noScriptCSS);

</script>



In this example, the noscript CSS file is always in the document and it is then removed using JavaScript immediately. I haven't tested this, but my first thought was that I would need to investigate if there would be a flicker on the screen as the page is reflowed, affecting the rendering performance of the page. My second thought is that this technique involves an additional HTTP request for all users not only those who need it.

There is another well known technique which involves writing your CSS assuming that JavaScript is not available and then including a script enabled CSS file using JavaScript as the page is being rendered. I am not a fan of this technique as I prefer not to write my CSS in this way.

There are a variety of other techniques as well such as changing a class on the BODY tag using JavaScript and cascading your selectors from that. If using this technique I would always have a noscript class on the BODY and then remove that (again, it fits better with the way I like to write my CSS).

This issue often raises its head and frankly I am now not fully satisfied with any of these techniques. So what do you think? What is the best way of handling this issue?

1 comment:

Anonymous said...

I've also seen this method: http://www.learningjquery.com/2008/10/1-awesome-way-to-avoid-the-not-so-excellent-flash-of-amazing-unstyled-content. It adds class "JS" to the "html" tag. But there's a problem - IE don't like when we try to manipulate DOM when it's not fully loaded. Sometimes it just hangs not able to load (on some versions). I think your second method will also have such problems because of that. Thus using noscript is the best method... probably.