There’s no denying that JavaScript can provide a much more pleasant user experience. There have always been usability and accessibility concerns tied to JavaScript, but only recently have those concerns been carefully minded (by many people). The first round of widespread JavaScript adoption resulted in obtrusive documents with error prone scripts that were hit or miss as far as browser support was concerned. Times have taken great change for the better, and now JavaScript can be properly implemented to progressively enhance many documents.
There have been many pieces written on both graceful degradation as well as progressive enhancement. Some people feel that they’re one and the same, but personally I think they are very similar, but each have unique characteristics. While a document that gracefully degrades will transparently appear as normal to any reader, progressively enhancing the document adds layers of functionality, if available, after the fact.
Relating Progressive Enhancement to Your CSS
Many times when you read about progressive enhancement on the Web, the discussion revolves around JavaScript. The general idea is to provide unobtrusive JavaScript that will not interfere with the viewing of any document, regardless of browser capability. As Web based applications become more advanced, there are many visual features being included to [hopefully] benefit the reader.
What’s unfortunate is that it is becoming more common for designers to neglect progressive enhancement once unobtrusive JavaScript is obtained. There are countless JavaScript libraries available, full of code that is designed with progressive enhancement in mind. The issue that’s becoming increasingly problematic, in my opinion, is the associated style that is required to achieve desired visual effects.
If your document will be enhanced when a reader doesn’t have a JavaScript equipped Web browser, it’s equally important that your CSS doesn’t interfere. While JavaScript should only control document behavior, that behavior often involves making changes to the DOM that are in turn effected by the document style.
As an example, there are many times that designers will adjust the visibility
or display
of an element in their CSS for the sole purpose of toggling that property at some point. What’s important to keep in mind is that readers without a JavaScript enabled browser will apply the entire style sheet, but have no script available to execute that fancy Ajax animation.
Use JavaScript to Progressively Enhance your CSS
In my opinion, there’s nothing wrong with altering the visibility
or display
of certain elements to bring your Web application together. It’s important to keep in mind the necessity of retaining progressive enhancement with your CSS as well.
On a recent project I ran into a situation in which I wanted certain elements to have stylistic elements that required JavaScript for full functionality. It would have been a nice feature to add, but requiring JavaScript isn’t an option. I needed a way to separate a small bit of CSS which would only be applied if the reader were able to make use of the JavaScript provided with the document.
I was reminded of an article I had read some time ago (that I’m having trouble locating) which mentioned using JavaScript to manipulate the DOM and add your CSS. This way, the styles are only applied using the technology which will control other document behavior. What we’ll do is generate a link
element, append the proper attributes, and finally insert our element into the document tree by placing a snippet in the head
.
<script type="text/javascript">
//<![CDATA[
initStyles = document.createElement("link");
initStyles.setAttribute("rel","stylesheet");
initStyles.setAttribute("type","text/css");
initStyles.setAttribute("media","screen,projection");
initStyles.setAttribute("href","css/js-init.css");
document.getElementsByTagName("head")[0].appendChild(initStyles);
//]]>
</script>
This snippet allows us to include the CSS to ‘initialize’ the document in preparation for user interaction via JavaScript. The style will only be applied if your reader has a JavaScript enabled browser, making it extremely likely that your Web app JavaScript will operate as intended.
It’s not the only way
Appending a style sheet to your document using a method like this may not be ideal in your opinion. You could effectively use your existing CSS and manipulate the DOM in a way that doesn’t interfere at all with a JavaScript-less reader. I’m not a fan of using JavaScript to directly control the style of an element. To me, (something like) element.style.color = 'red'
triggers nightmarish images of <FONT color="red">Lorem ipsum</FONT>
. I try to stray away from using document behavior to control document style, that’s reserved for CSS.
What is truly important is ensuring your document is still equally usable whether you’re working with JavaScript or not. That goes beyond taking your scripts into consideration, any preparation you create with CSS must be monitored as well.
Comments
[…] Applying Progressive Enhancement to Your CSS (with JavaScript) include the CSS to ‘initialize’ the document in preparation for user interaction via JavaScript. The style will only be applied if your reader has a JavaScript enabled browser (tags: CSS JavaScript) […]
I’ve use this technique as well, but you don’t have to use DOM creation/manipulation syntax if you don’t want to. You can just use document.write() to explicitly add the link tag within the head tags of the site. Either way works, but just about any level of javascript experience can understand document.write() but not everyone’s familiar with the DOM manipulations.
The problem with the method which you mention is that you need to keep your javascript css and your regular css separated.
jQuery’s document.ready() is a nice function, but if you start digging you notice that it relies on browser-sniffing and browser-specific code, which isn’t nice at all.
The document.write() in your head-tag works, but it’s not really that elegant either.
One method that I’ve grown quite fond of is to add the class “hasJS” to the body of the document (not via the document.onLoad-event, but rather in-line javascript just like you suggest in this article). This way you can add js-specific styles to the same css-file using the .hasJS CSS class selector.
@David Kees: Personally I have the same as Fredrik in that document.write, to me, isn’t very elegant. You’re right, it could work.
@Fredrik Wärnsberg: That’s what I wanted to touch on in the article. I think something like
.hasJS
is another good way to solve the issue at hand. I’m not a huge fan of separating style sheets to be honest, but I was willing to stretch for this circumstance.[…] written about applying progressive enhancement to your CSS in the past, but John’s article goes above and beyond my idea. To summarize the idea behind […]