Pragmatic Progressive Enhancement

Preview:

DESCRIPTION

An introduction to the why and how of progressive enhancement, given as a brownbag at AKQA UK

Citation preview

Progressive Enhancement

Christian Heilmann, AKQA Brown Bag, London, May 2008

Playing it safe in unknown territory

As web developers, we are working with the unknown.

Right from the start the web was meant to be independent of display unit and rendering

device.

This is the reason why web standards are so low level

technologies.

There is not much sophistication in HTML – but a

lot of portability.

Simplicity means sturdiness – not much can break.

Simplicity also means easy adaptation to environments.

There is hardly any more hostile environment than the

web.

You have no clue whatsoever about the technology, the

ability or the personal settings of the end user.

If you embrace this fact, you are ready to become a good

developer.

Good developers are lazy – they don’t want to do the

same thing twice.

Instead, we find solutions that do the job for us.

One of these is progressive enhancement.

Instead of building a solution based on assumptions...

“Everybody has JavaScript enabled and a fast computer”

“All our users have a resolution of 1280 x 1024”

“Yeah, 40 menu entries are OK, there is enough space on

the screen”

... we work in a paranoid fashion.

Things *will* break and the person who created the

interface will get the blame.

Does this mean we need to dumb down our solutions?

Does it mean JavaScript and Flash and Silverlight are evil?

Only if we built them evil.

Or if we build them badly.

Used the correct way, JavaScript can help you build

amazingly adaptive and clever applications.

Seven steps to take to enhance progressively:

1. Separate as much as possible.

2. Build on things that work

3. Generate dependent markup

4. Test for everything before you apply it.

5. Explore the environment

6. Load on demand

7. Modularize code

Let’s go through them in detail...

1. Separate as much as possible.

Separation of structure (HTML), presentation (CSS)

and behaviour (JS) is an absolute must.

The reason is pragmatism.

You leave it up to the browser to apply what it can support.

You also know exactly where to change what

(and you will have to change things constantly)

2. Build on things that work

Using JavaScript, you can make anything interactive.

Using CSS, you can make anything look like something

it isn’t.

With great power comes great responsibility.

You simulate interaction that is most likely a lot more complex than you think.

Interactive elements can be used with a lot of different

input devices.

They also report to all kind of systems when activated and trigger appropriate actions.

If you simulate, do it right – don’t break expectations.

Users trust you to give them a working system – this is what

they came for.

Best to use what works – links, forms and buttons.

<span onclick=”help()”>Help</span>

<a href="/help" id="help">Help</a><script>YAHOO.example.helpdemo = function(){ function doHelp(){ // other work here... } YAHOO.util.Event.on('help','click',function(e){ doHelp(); YAHOO.util.Event.preventDefault(e); });}();</script>

3. Generate dependent markup

If your script needs HTML that only makes sense when being

driven or changed by JavaScript, generate it with

JavaScript.

Examples are window.print() links or anything that pulls in

data only when JS is available.

Using the DOM you can create whatever you need.

4. Test for everything before you apply it.

This is a no-brainer, as you cannot trust circumstances.

Remember “check the depth of the pool before you jump

in head-first”?

<script type=”text/javascript”> var c = document.getElementById(‘info’); var text = document.createTextNode(message); c.appendChild(text);</script>

You cannot modify properties of the unknown!

<script type=”text/javascript”> var c = document.getElementById(‘info’); if(c){ var text = document.createTextNode(message); c.appendChild(text); }</script>

The same applies to any browser or DOM method or attribute you try to access.

JavaScript has conditions.

Use them.

5. Explore the environment

Browsers tell you a lot about themselves when you use JavaScript and the DOM.

You get the browser viewport size, how far down the

document the user scrolled, where the mouse pointer is

and much more.

You can use this to make sure things don’t break.

For example menus or panels.

6. Load on demand

One of the biggest issues on the web is performance.

Things are never fast enough.

Therefore it is a good idea to load extraneous content and

code needed to support it only when you need to.

You can for example test which images are visible (by

comparing their location with the viewport) and only load

them when they are.

You can also start with a really small script that

generates script nodes with the DOM to pull in larger

library code when and if it is needed and can be applied.

7. Modularize code

This happens in several ways.

First of all you want to ensure that your code does work

nicely with other code.

The easiest way to do that is the module pattern.

<script type=”text/javascript”> function init(){ // initialization } function show(){ // show stuff } init();</script>

<script type=”text/javascript”> modules = function(){ function init(){ // initialization } function show(){ // show stuff } init(); }();</script>

<script type=”text/javascript”> modules = function(){ function init(){ // initialization } function show(){ // show stuff } init(); return { init:init, show:show } }(); // modules.init(); // modules.show();</script>

<script type=”text/javascript”> (function(){ function init(){ // initialization } function show(){ // show stuff } init(); })();</script>

The other kind of modularization that makes

sense is collating scripts and CSS definitions into different

files.

This eases maintenance and also helps loading on

demand.

It is not good for performance, but techniques to work around that issue is

another talk :)

Now you know the tricks and their rationale and you have

a choice.

You can start using them with your own code and enter a world of pain and misery

called cross-browser issues.

Or you can use a JavaScript library and CSS framework

that does it for you.

All good frameworks and libraries want to do two

things:

Make your life a lot easier by normalizing browser

behaviour.

and

bridge the gap until browsers are good and do what we tell

them to do.

One of those libraries is YUI:http://developer.yahoo.com/yui/

★ CSS Framework

★ JavaScript Utilities

★ Widget library

★ Skinable

★ Extendable and Modularized.

★ Powers Yahoo! pages

★ BSD licensed (commercial use is OK)

Usable, progressively enhanced applications and

sites are not science fiction or “best case scenarios”.

They are achievable by subscribing to the ideas of progressive enhancement and using the right tools.

When we cut corners, we hurt ourselves the most.

Taking pride in our job, targeting maintainability and

extendability will make us happier developers and give us more confidence to give

achievable estimates.

THANKS!

Recommended