Showing posts with label Progressive enhancement. Show all posts
Showing posts with label Progressive enhancement. Show all posts

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?

7 January 2009

Using CSS3

Despite ones personal feelings about it, I am really keen to start using CSS3. There are a number of browsers with support for some of the interesting parts of CSS3 and I think there is a new opportunity to use our skills of progressive enhancement to create some really exciting new effects.

If we wisely apply the appropriate properties, we can enhance the user experience for some users - and an increasing number of users - whilst offering a more than acceptable experience for the remainder of our users.

There may be a useful side effect here as well. When people see a site enhanced by the latest web browsers, we may get more users switching from older and less standards compliant browsers to the more modern and better newer browsers.

We may have to use vendor specific prefixes to get some effects to work, but I think that is a small price to pay to help push forwards the use of the good parts of CSS3.

The best part of all this is that as new browsers are released and used, our websites will look better and a good level of support is on the horizon. Safari 3 already has a good level of support, IE8 will have some and Firefox 3.1 will have a good level of support. With Safari having decent support for CSS3, it means all modern Webkit browsers should as well - read Chrome and the iPhone browser in particular!

So which properties might be able to be used in this way? Here are a few select ones that I think could be useful:

box-shadow
With this effect, we can create drop shadows around boxes. When this property is not understood, there is no detrimental effect and when it is recognised, a nice enhancement can be achieved.

border-radius
This effect allows us to create rounded corners using only CSS. I think this is useful as its simpler than any other technique and support can be achieved for IE by using conditional comments to include other stylesheets. Firefox 3 and Safari 3 already have support for this property - definitely one of the most useful to start implementing.

text-shadow
Similar to box-shadow, this effect will create a drop shadow effect around text. Another nice enhancement. Not strictly a new addition in CSS3, but support seems to be coming with CSS3 support.

There are other interesting effects coming, but I think these are the most potentially useful when applied using the principles of progressive enhancement. There are also a couple of useful new selectors coming, but its hard to see how one could use them with the principles of progressive enhancement.

I am excited about some of the new features of CSS3 and its great to be able to start using some. Indeed, the new JSquared website will feature some new CSS3 effects applied in this way.

What we do need to be cautious of though is creating a complete maintenance headache. Lets start using new features, but sparingly at first. We dont want to make development even harder with yet another class of browser to support.

27 April 2008

Enhancements to CSS

This post presents an interesting idea, that of CSS variables. On the surface, this could be a brilliant idea, though there are some potential flaws.

Firstly, there is the issue of redefinition - if a variable is defined and then redefined. This is particularly pertinent if the variable has been used before it is redefined.

Then there is the issue of CSS injected via JavaScript. The final issue I will raise about this is browser support.

Browser support is an issue which is close to my heart and about which I feel strongly. I firmly believe that with progressive enhancement, sensible design and tolerance of some differences between browsers from the client, a website can be made to support multiple browsers with minimal effort.

New innovations are fantastic and should be encouraged, but changes in the CSS specs can cause issues. We cannot start using this sort of new feature until a major proportion of users are accessing your website with a browser which supports the new feature.

So, what can we do about this? It is hard to reconcile the need for general cross-browser support and the desire for improvements and more features in the underlying specifications we use to build websites.

As I see it, there are a number of things that can be done. Firstly, we can educate our clients that it is ok for there to be differences. Secondly, we could build websites in "the classic manner" and also include the CSS style rules introduced by updates to the specification - but this may not work that successfully for obvious reasons.

As always, us interface developers will generally overcome these issues with a combination of techniques based on the principles of building to web standards and that of progressive enhancement.

What do you think we can do to overcome these issues? How can we bring about changes and enhancements as wide ranging as CSS variables without compromising the installed base of users who do not support new features and who can take many years to upgrade?

31 March 2008

Progressive degradation

I should start this post with a disclaimer. I did not discover or invent this technique. It was suggested to me by a now ex-colleague, Marcus. He also does not like what I have named this technique. But you can make your own mind up.

We should by now all be aware of progressive enhancement, what it is and why to use it. Well, progressive degradation actually assists with progressive enhancement and in some ways turns the idea on its head to make life easier and simpler. Whenever I have employed progressive degradation, I have found things easier to develop and maintain.

Progressive enhancement generally involves writing high quality semantic markup and then layering onto that additional elements which do not in themselves add additional meaning but enhance the visual presentation of the content of a web page or make it easier and nicer to use.

Generally progressive enhancement will mean layering CSS on to the markup to make the web page look nice, and JavaScript to make the web page easier and nicer to use. Progressive degradation turns that idea on its head.

With progressive degradation, we still need high quality semantic markup. That is always the base. We are still going to layer CSS on to the markup to make the web page look nice. The big change is with the JavaScript.

Using progressive enhancement, we would write the CSS in such a way that if the user does not have a JavaScript enabled browser, the site works well and looks correct. If the user does have a JavaScript enabled browser, the JavaScript code itself would make changes to the way the CSS is applied (and perhaps to the markup as well) to give the web pages a slightly different look and additional behaviours.

Using progressive degradation, we apply the CSS to the markup in the assumption that the user has a JavaScript enabled browser. Let me just make that clear. We make the assumption that the user has JavaScript enabled within their browser.

So where is the magic? The trick is that we include an additional CSS file for those users who DO NOT have JavaScript enabled in their browser which will re-style the content to be usable without the JavaScript enhancements.

This technique is not suitable for all occasions, but when I have employed it within a website, I have found a way to use it for every enhanced element.

The major advantage of progressive degradation is that there is no page flicker as the content is altered by JavaScript code even when the JavaScript code is run on page load as the CSS code that is loaded with the page sets up the page for the JavaScript enhanced version from load.

Its an extremely simple technique to apply and the following code is all you need:

<noscript>

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

</noscript>


As you can see, all that is involved is the addition of a CSS file inside noscript tags. Whilst this does make the markup for your web page invalid, I believe it is a small price to pay for the power it brings. To demonstrate that power, an example could be useful.

The example I will use is that of a form which will add an item to a list. Without JavaScript, the form will always be visible. With JavaScript, there will be an add button which when clicked will show the form. How the form submission is handled here is not important but one could use an AJAX request for those user agents which support it and a postback cycle for those which do not.

The 2 versions of this page element look as follows:

With JavaScript enabled:



Without JavaScipt enabled:



The markup is as follows:

<div id="ListContainer">

<ul>

<li>Item 1</li>

<li>Item 2</li>

</ul>

<form action="page.html" method="post">

<label for="NewItem" id="NewItemLabel">Add item</label>

<input id="NewItem" type="text" />

<input type="submit" id="SubmitForm" value="add" />

</form>

</div>



The pertinent CSS for the purposes of this article is:
#NewItem, #SubmitForm {

display:none;

}


This CSS will hide the input field and the submit button.

The following (somewhat rough) JavaScript will make the progressive enhancement work so that when clicking on the label for the form field, the input field and submit button will show:
<script type="text/javascript">

window.onload = function() {

document.getElementById("NewItemLabel").onclick = function() {

this.style.display = "none";

document.getElementById("NewItem").style.display = "block";

document.getElementById("SubmitForm").style.display = "block";

}

}

</script>


So, we now have a working form module as described above. When the page loads, some elements are hidden - there is no flicker whilst the JavaScript kicks in on page load and hides the relevant elements as they are already hidden! Clicking on the label will hide the label and show the relevant elements.

Now for the progressive degradation:
<noscript>

<style type="text/css">

#NewItem, #SubmitForm {

display:block;

}

</style>

</noscript>


And that is all there is to it. Without JavaScript enabled in the web browser, the user will see the complete form. With JavaScript enabled, the user gets an enhanced experience. If you re-read the last 2 sentences, you will notice how right it sounds and yet we are mixing the concepts of progressive enhancement with those of progressive degradation.

Of course we could take this example much further, writing some JavaScript to allow the user to return the page to its load state if they changed their mind and did not actually want to add another list item. We could write code to handle the form submission etc and all this would be progressive enhancement, but progressive enhancement made even easier by starting with the concept of progressive degradation.

The key to how progressive degradation makes this easier is that we know the non-JavaScript version of the page will work perfectly and we can add as much progressive enhancement as we like and concentrate on writing fantastic JavaScript to enable exciting but as always simple and light-touch enhancements to the web pages we build.

7 January 2008

Is CSS the ultimate expression of progressive enhancement?

Following up on my previous post about progressive enhancement, I wish to pose the question:
Is CSS the ultimate expression of progressive enhancement?

To help us address the question, lets briefly remind ourselves that progressive enhancement is a technique whereby the way a web page operates is enhanced if the user agent being used supports certain features but if the user agent does not, then nothing is lost. The user can still see all content and use all features of the web page.

So, does this hold true of CSS? Well, given valid markup, I believe it does and I certainly believe it should.

That does not answer the question posed though. I am firmly of the opinion that the answer is yes. CSS is so powerful and so able to change the way a web page looks but without itself forming any part of the content or functionality of that web page, that I believe it must be the ultimate expression of progressive enhancement.

Do you agree? Do you disagree?

13 December 2007

Progressive enhancement

In the world of interface development today there is one technique to which I fully subscribe without hesitation or regret - progressive enhancement. It is for me the guiding principle behind almost all of the work I do.

Progressive enhancement can mean a number of things but in a nutshell, it involves taking a base line for a web page and layering on enhancements which are not required in order to use the web page or to understand the content of the web page. If the browser being used can understand these additional layers, then they will be applied and will enhance the way the web page operates or looks.

The base line is the HTML code of the web page. The HTML code defines the content of the web page. The HTML of course should be semantic and where possible valid. In order to define the content of the page, the HTML code should be well structured, for example having a sensible header nesting order.

Given semantic and well written HTML, the content of a web page should be accessible to any user agent. The job of progressive enhancement is to layer on some additional "features".

There are two main forms of progressive enhancement used presently. It is in fact possible to argue that there are 3 or possibly 4 forms (and maybe even more), but the two main forms are CSS and JavaScript (I would perhaps also say that images are another main type of progressive enhancement - with well written alt attributes on image tags, the images are not necessary to understand the page).

So what do these forms of progressive enhancement do and how do they work?

CSS
The way the web page looks is defined by the CSS code used to style the page. The stylesheet uses a series of selectors to select elements defined in the HTML code and apply one or more of a wide variety of styling effects. These include applying borders, text colours, background colours and images, sizes and many many others.

JavaScript
Any behaviours not handled by the browser by default can be added through the use of JavaScript. JavaScript is a programming language with a C type syntax which is the language of choice for the web. The JavaScript code can perform a massively wide variety of different operations. These range from simple form validation scripts to whole applications such as Google Maps.

Progressive enhancement gives us a very powerful structure to building web pages. Using this technique, we create by default a separation between code for content, visual style and behavior. We are compelled to consider the implication of our enhancements and to make visual and behavioural aspects of the web page just that, enhancements and not requirements.

What will the page be like to use if the user agent does not support CSS? How will the core functions of the page operate without JavaScript enabled in the browser? By considering these questions, we are forced to write better HTML. In fact we are forced also to write better CSS and JavaScript. Everything needs to be considered carefully to ensure the separation of code remains and that the web page will be usable without the enhancements being available.

Not every web page can be progressively enhanced. In that instance, the appropriate alternative is a fallback version. Try browsing to Google Maps with JavaScript disabled in your browser and you will be taken to a page which will work without JavaScript. Not all fallbacks are this drastic, but a fallback allows the principle of progressive enhancement to be applied even in those few cases when the effort involved in using this approach is prohibitive.

The vast and overwhelming majority of the time, progressive enhancement makes writing a web page easier. The code will be better, cleaner and more maintainable. The web page more accessible and inclusive. The interface developer can be happy with a job well done!