I like this article. There is something that feels so right when seperating things out like this.
I still struggle with one thing though – the content jump. The page loads with all HTML needed and then JS comes along to do whatever you need it to do. Often this may be hiding some panels so they can be expanded by the user. So you see the content while the page is loading then it moves/toggles/disappears. Has anyone got a graceful way to get around this while keeping with ultimate separation of JS only in external files?
Copy & paste the code below to embed this comment.
Jon Cram
@Alex Bobin: you need to apply the JS before the content is rendered.
I suspect you’re applying your JS when the onload event for the document kicks in.
Switching to the ondomready event will sort things out. This event is fired when the DOM has finished loading and before the content is rendered – any JS changes you make are applied before anything is displayed to the user.
I realize A List Apart is catering to a wide audience, but this article seems a bit on the basic side. For anyone who has been reading ALA for a while, or who read Jeremy Keith’s DOM Scripting book, has been using these techniques as second nature for quite a while.
How about some juicy details, like “techniques for keeping your presentation out of your scripts”?
In answer to “Nora’s question”:/comments/progressiveenhancementwithjavascript?page=2#14 on techniques for keeping presentation and scripting separated, I recommend checking out the article I wrote for Scroll (referenced in this article). Christian Heilmann and Nicholas Zakas have been working on this topic as well and my article summarizes their recommendations as well as those I’ve come up with.
If you can’t get a copy of Scroll, I will be re-publishing the full article for free on the web in a few weeks (when my contract with them allows me to).
As for libraries, that may be a future article, we just need to make sure everyone’s on the same page first and I’m amazed how many people haven’t grasped what Progressive Enhancement is yet.
Copy & paste the code below to embed this comment.
Tom Lee
Nothing you’re saying is wrong, per se, but it’s a bit outdated. As others have noted, this sort of work is best accomplished with the use of a JS toolkit. I, too, am a JQuery fan, but there are plenty of other very good, very small ones out there.
You’re doing your readers a disservice by not discussing toolkits (presumably in an attempt to avoid advocating any particular one). There’s no good reason for this.
Copy & paste the code below to embed this comment.
Tom Lee
I’ll point out that, under some circumstances, there are perfectly good reasons for using inline JS rather than included external JS files. Inline JS can produce rendered elements faster (if the DOM is ready for it or not needed) and can eliminate the need for an extra HTTP trip, resulting in speedier page loads.
Copy & paste the code below to embed this comment.
Richard Cotton
Supporting what Tom said above; if building a site with an MVC framework, frequently the place for some of the javascript is inline in the view it forms part of.
Keeps the view itself atomic, and also reduces the number of http requests.
Load your framework in the head, having concatenated all your plugins to give one .js include, then inline the code that uses that framework at the appropriate point. (this code is specific to that view, so it belongs with or in that view…)
And yes; as said above, use onDomReady – by using a framework that handles this for you. I honestly believe that only 2 breeds of programmer use bare javascript now; those writing frameworks, and masochists.
Write your page with everything displayed, then use javascript to collapse / hide / emellish elements you want to – therefore meaning that no-js users get a full page of content. (just like if you markup your menu as a list, no-css users still get a usable menu, just ugly. no-js users should get a usable menu, just with all the levels displayed all the time, for example)
Don’t add content in javascript; that means no-js users miss out on it entirely.
Remember that you can have classes and ids that are only there for javascript to pick up on, and that you can also have classes in your CSS that are only there for javascript to assign and remove dynamically – this is much more maintainable than writing to the style attribute in your javascript.
Interesting article, but i also agree with the JQuery fans such as Tom Lee. Nowadays I see very little need for custom JavaScript in applications when libraries such as JQuery are so well established and stable?
Would may be good is the next article showing how progressive enhancement can be achieved with minimal code and the use of such a library?
I admit that some larger clients will prefer not to use an “off the shelf” solution but if they are going to save time on development costs there is a logical argument for this to be the way forward.
Let me get this straight. The ideas is to replace the inline onClick event with an ID, right? Then manipulate it with getElementById? That’s genius! LightBulb=On What a simple, yet powerful technique. The other ideas are great and are already incorporated into my modus operandi. But I smell a forth article on this subject coming soon, yes? I’m sure there’s more to this story.
Jus thought I’d mention a brilliant tool for when you’re going round looking for obtrusive scripts to remove: the “Obtrusive JavaScript Checker”:http://www.robertnyman.com/2008/11/08/obtrusive-javascript-checker-08-proper-firefox-extension-release-with-live-enabling-and-disabling/ Firefox extension.
Copy & paste the code below to embed this comment.
John K
From the article:
Approaching the challenge in this way, you have not only met the requirements, but you have also provided a “lo-fi”? experience for search engine spiders and users without JavaScript.
Providing a “lo-fi” experience sure sounds a lot like graceful degredation to me.
In modern web development, I how can someone plan rich interactions by not thinking about rich interactions from the beginning? Planning rich interactions using Javascript and providing a low-fi experience is still graceful degredation.
Providing a “lo-fi”? experience sure sounds a lot like graceful degredation to me.
Taken as a literal binary JS/no JS switch, yes, but when combined with capability testing against the browser, you can develop many levels of (progressively enhanced) experience for users with varying levels of JavaScript support. In other words, it’s not an all or nothing (which is how Graceful Degradation has been practiced in many circles) experience, but rather one in which the fidelity of that experience is directly tied to the capabilities of the device and user agent accessing it. That’s what makes it progressive.
The relationship between the two terms can perhaps best be viewed this way: all progressively enhanced interfaces also gracefully degrade, but not all gracefully degrading interfaces are progressively enhanced. Some may be, but it isn’t a guarantee. It all comes down to what your focus is during development and what decisions you make during the development process.
Copy & paste the code below to embed this comment.
Bill Sutton
This was a great article.
In the last full sentence of the second paragraph under Establishing a baseline, did you mean to say load it on the “client side” instead of “server side”?
Copy & paste the code below to embed this comment.
T J
I get Progressive Enhancement. It’s logical. It makes sense. It’s orderly, methodical, principled, and even elegant. I can see the advantage for site maintenance and modification. PE strives for capability inclusion and flexibility . . . for (it seems) relatively simple content, that is, content with limited or lenient interactivity requirements.
One of the principles stated as underlying PE is that the basic content and functionality of a site is preserved at all levels of “enhancement.” That is not true for sites that require a given level of interactivity. PE seems to fulfill its purpose for sites where interactivity is the icing, not the cake.
How does PE uphold its promise for web applications, whose sole purpose is to provide a highly interactive, application-level web interface to solve a given problem? Sure, the principles of PE can still be used as a developer paradigm, but the end result will not provide basic functionality at all levels of “enhancement.” Doesn’t that fail to honor a PE principle?
If a site can not progress enough to enable its minimum functionality, what good does it do to cater to lo-fi? This question points out one difference in principle between Graceful Degradation and Progressive Enhancement. With GD, developers readily tell the user, “You don’t have what it takes to run this app.” With PE, developers are supposed to provide basic functionality at all levels of capability and only say, “It gets better from here!”
I like the idea of PE. What I’m wrestling with is seeing it as the sole paradigm for web development, unless the developer just likes the orderly approach (which I do).
Thanks for the very informative and clearly written articles.
28 Reader Comments
Back to the ArticleRobert Grant
I agree with the above people who love jQuery, it’s perfect for this.
Alex Bobin
I like this article. There is something that feels so right when seperating things out like this.
I still struggle with one thing though – the content jump. The page loads with all HTML needed and then JS comes along to do whatever you need it to do. Often this may be hiding some panels so they can be expanded by the user. So you see the content while the page is loading then it moves/toggles/disappears. Has anyone got a graceful way to get around this while keeping with ultimate separation of JS only in external files?
Jon Cram
@Alex Bobin: you need to apply the JS before the content is rendered.
I suspect you’re applying your JS when the onload event for the document kicks in.
Switching to the ondomready event will sort things out. This event is fired when the DOM has finished loading and before the content is rendered – any JS changes you make are applied before anything is displayed to the user.
Nora Brown
I realize A List Apart is catering to a wide audience, but this article seems a bit on the basic side. For anyone who has been reading ALA for a while, or who read Jeremy Keith’s DOM Scripting book, has been using these techniques as second nature for quite a while.
How about some juicy details, like “techniques for keeping your presentation out of your scripts”?
Aaron Gustafson
In answer to “Nora’s question”:/comments/progressiveenhancementwithjavascript?page=2#14 on techniques for keeping presentation and scripting separated, I recommend checking out the article I wrote for Scroll (referenced in this article). Christian Heilmann and Nicholas Zakas have been working on this topic as well and my article summarizes their recommendations as well as those I’ve come up with.
If you can’t get a copy of Scroll, I will be re-publishing the full article for free on the web in a few weeks (when my contract with them allows me to).
As for libraries, that may be a future article, we just need to make sure everyone’s on the same page first and I’m amazed how many people haven’t grasped what Progressive Enhancement is yet.
Divya Manian
That you wrote for scroll. This article does seem to be on the basic side. would love to read more about progressive enhancement.
Tom Lee
Nothing you’re saying is wrong, per se, but it’s a bit outdated. As others have noted, this sort of work is best accomplished with the use of a JS toolkit. I, too, am a JQuery fan, but there are plenty of other very good, very small ones out there.
You’re doing your readers a disservice by not discussing toolkits (presumably in an attempt to avoid advocating any particular one). There’s no good reason for this.
Tom Lee
I’ll point out that, under some circumstances, there are perfectly good reasons for using inline JS rather than included external JS files. Inline JS can produce rendered elements faster (if the DOM is ready for it or not needed) and can eliminate the need for an extra HTTP trip, resulting in speedier page loads.
Richard Cotton
Supporting what Tom said above; if building a site with an MVC framework, frequently the place for some of the javascript is inline in the view it forms part of.
Keeps the view itself atomic, and also reduces the number of http requests.
Load your framework in the head, having concatenated all your plugins to give one .js include, then inline the code that uses that framework at the appropriate point. (this code is specific to that view, so it belongs with or in that view…)
And yes; as said above, use onDomReady – by using a framework that handles this for you. I honestly believe that only 2 breeds of programmer use bare javascript now; those writing frameworks, and masochists.
Write your page with everything displayed, then use javascript to collapse / hide / emellish elements you want to – therefore meaning that no-js users get a full page of content. (just like if you markup your menu as a list, no-css users still get a usable menu, just ugly. no-js users should get a usable menu, just with all the levels displayed all the time, for example)
Don’t add content in javascript; that means no-js users miss out on it entirely.
Remember that you can have classes and ids that are only there for javascript to pick up on, and that you can also have classes in your CSS that are only there for javascript to assign and remove dynamically – this is much more maintainable than writing to the style attribute in your javascript.
Digital Agency
Interesting article, but i also agree with the JQuery fans such as Tom Lee. Nowadays I see very little need for custom JavaScript in applications when libraries such as JQuery are so well established and stable?
Would may be good is the next article showing how progressive enhancement can be achieved with minimal code and the use of such a library?
I admit that some larger clients will prefer not to use an “off the shelf” solution but if they are going to save time on development costs there is a logical argument for this to be the way forward.
John Kulunk
Let me get this straight. The ideas is to replace the inline onClick event with an ID, right? Then manipulate it with getElementById? That’s genius! LightBulb=On What a simple, yet powerful technique. The other ideas are great and are already incorporated into my modus operandi. But I smell a forth article on this subject coming soon, yes? I’m sure there’s more to this story.
Matthew Babbs
Jus thought I’d mention a brilliant tool for when you’re going round looking for obtrusive scripts to remove: the “Obtrusive JavaScript Checker”:http://www.robertnyman.com/2008/11/08/obtrusive-javascript-checker-08-proper-firefox-extension-release-with-live-enabling-and-disabling/ Firefox extension.
John K
From the article:
Approaching the challenge in this way, you have not only met the requirements, but you have also provided a “lo-fi”? experience for search engine spiders and users without JavaScript.
Providing a “lo-fi” experience sure sounds a lot like graceful degredation to me.
In modern web development, I how can someone plan rich interactions by not thinking about rich interactions from the beginning? Planning rich interactions using Javascript and providing a low-fi experience is still graceful degredation.
Aaron Gustafson
Taken as a literal binary JS/no JS switch, yes, but when combined with capability testing against the browser, you can develop many levels of (progressively enhanced) experience for users with varying levels of JavaScript support. In other words, it’s not an all or nothing (which is how Graceful Degradation has been practiced in many circles) experience, but rather one in which the fidelity of that experience is directly tied to the capabilities of the device and user agent accessing it. That’s what makes it progressive.
The relationship between the two terms can perhaps best be viewed this way: all progressively enhanced interfaces also gracefully degrade, but not all gracefully degrading interfaces are progressively enhanced. Some may be, but it isn’t a guarantee. It all comes down to what your focus is during development and what decisions you make during the development process.
Bill Sutton
This was a great article.
In the last full sentence of the second paragraph under Establishing a baseline, did you mean to say load it on the “client side” instead of “server side”?
Aaron Gustafson
That’s exactly what it should have said, thanks Bill.
T J
I get Progressive Enhancement. It’s logical. It makes sense. It’s orderly, methodical, principled, and even elegant. I can see the advantage for site maintenance and modification. PE strives for capability inclusion and flexibility . . . for (it seems) relatively simple content, that is, content with limited or lenient interactivity requirements.
One of the principles stated as underlying PE is that the basic content and functionality of a site is preserved at all levels of “enhancement.” That is not true for sites that require a given level of interactivity. PE seems to fulfill its purpose for sites where interactivity is the icing, not the cake.
How does PE uphold its promise for web applications, whose sole purpose is to provide a highly interactive, application-level web interface to solve a given problem? Sure, the principles of PE can still be used as a developer paradigm, but the end result will not provide basic functionality at all levels of “enhancement.” Doesn’t that fail to honor a PE principle?
If a site can not progress enough to enable its minimum functionality, what good does it do to cater to lo-fi? This question points out one difference in principle between Graceful Degradation and Progressive Enhancement. With GD, developers readily tell the user, “You don’t have what it takes to run this app.” With PE, developers are supposed to provide basic functionality at all levels of capability and only say, “It gets better from here!”
I like the idea of PE. What I’m wrestling with is seeing it as the sole paradigm for web development, unless the developer just likes the orderly approach (which I do).
Thanks for the very informative and clearly written articles.
facundo
Very clear and usefull, thanks for share it with us.