making your site html5 ready pt2/the gentlemen way

published on:
November 12, 2009 / 11:48
comments

Last week's article explained the main pitfalls of using new structural html5 elements. This second part will explain how to be a true gentleman to those people you've left in the cold by deciding to switch to html5. The method described below isn't perfect and could possibly use some tweaking, but as far as graceful degradation goes, I believe it's pretty solid.

The following solution was developed for people visiting with IE and javascript disabled. They fail to benefit from the html5 shiv trick and end up with a whole lot of non-styleable elements, completely ruining the design you've so carefully constructed. Depending on your visitor's demographic the following measures might be a bit over the top, but they were conceived to be as thorough as possible. Just a little warning.

detecting there is no javascript

document.body.className = document.body.className.replace("noJS", "");

Our first problem is finding out if a user has javascript enabled, which brings us to a rather interesting technique that could be used independent of the whole html5 deal. The trick is to add a .noJS class to the body element of every page. Then, first thing after opening the body tag we insert a little javascript removing this class. If the .noJS class is still present after that, you can be sure the user has javascript disabled. You can now use the .noJS class as a selector prefix for restyling elements when javascript is disabled.

Note that the javascript above "does the trick" and isn't the cleanest or leanest way possible to do this. Also note that this action should be done as quickly as possible, that's why I chose to do it right after opening the body tag. Unobtrusive ways require a longer waiting time and waiting for document loads or other events will most likely cause some graphical glitches as the base css might already be applied while loading the page. Modern browsers are getting quicker, but remember we're also doing this for IE6 users.

<!--[if lte IE 8]> <link rel="stylesheet" type="text/css" media="all" href="/style/html5-ie.css" /> <![endif]-->

The .noJS class can be used for all situations were no-javascript degradation is required, but in this case we only need it to handle IE browsers. That's why we'll create a separate css file for our downgraded design and serve the css through conditional comments. We can use the same conditional comment we created for the html5 shiv javascript file, which is quite nice. You now have all the means to serve javascript-less IE users a downgraded design.

how to be a gentleman

Serving a seriously degraded design is still a pretty drastic decision, and most people will probably fail to understand what has happened to your site. Just put yourself in their place. One day you are visiting a nice looking site, next you know the design went from nice to completely crap (but still usable). It's only fair to inform them why this is happening to them. Sadly, actually doing this in a clean way is not as easy as you might think.

Remember that we are doing this for IE users without javascript enabled. That means you can't use any normal overlays or spotlight effects to draw their attention. Also, I wanted the message to appear only once, namely the first time they visited my site after I switched to html5. Only on their specific demand should they be able to see the message again. It took us a while, but we worked out a solution. Here goes.

being a gentleman

First thing to do is to create an overlay which will be inserted the first time they visit your site after the switch. The .noJS class is extremely useful as you can style the overlay to show by default, effectively hiding the rest of your site. Simply add a specific class to the overlay you'd like to show and apply all styles to .noJS .your-preferred-classname. So now they know.

Of course, once they've read the message in the overlay you shouldn't bother them anymore. Setting a cookie is a good place to start. As long as the cookie is set (from the back-end, no javascript remember), you can make sure the overlay isn't inserted in the html code. So what about people without cookies? A bridge too far you say? Well, maybe, but with the current solution these people will keep getting the overlay for each page, and since they don't have javascript either the only way to reach a new page for them is through an actual page refresh, triggering the overlay again and effectively making your site completely inaccessible.

So we looked a bit further and came to the url referrer. This parameter (accessible in the back-end) will tell you where your user came from before he hit the current page. If your domain isn't in the referrer you can show the overlay, since you know it is the first page on your site he hits. If your domain is in the referrer, you keep the overlay out of the html code. This means that a visitor with javascript and cookies disabled will see the message with each visit, but that's his punishment for being so stubborn I guess. Some quick testing revealed that the referrer was also entered for new tab and new browser hits, which only works to our advantage.

Finally, you can add an additional check on the user client string, filtering out IE users. Another security measure it to delete the overlay with javascript on body load. This way, there's no way it will ever surface in the wrong circumstances. Furthermore, it's a good idea to add a little warning box which can trigger the overlay again at any time, overriding any of the previous conditions. There's always people who might want to read it again. This warning box can be easily hidden for javascript-enabled and non-IE users, using the noJS class.

conclusion

A whole lot of trouble for just a couple of visitors? Maybe, but you can take from this method whatever part you like. There's no shame in dropping the url referrer option, or to simply insert a contextual box for IE/non-javascript users which directs them to a separate page containing the message. This method is merely an exercise in graceful degradation, and trying to be as graceful as possible.

If you want to see it in action, visit my blog with IE and javascript turned off. You can even disable your cookies (and make sure to clear them first) to see the referrer option in action. Again, this method is a bit far-fetched, but it should give you all the means to be as polite about it as possible. If any other measures or workarounds exist, do let me know.

Comments

Chris Heilmann

comment number
date
November 15, 2009 01:43

Why not add a class called js with JavaScript to the body instead of removing one? seems an unnecessary step to me. Adding one has been a standard in unobtrusive scripting for years.

Niels Matthijs

comment number
date
November 15, 2009 09:35

Well, there's a pretty good reason.

If you add a class .js you would have to make the degraded design first, then overwrite everything using the .js prefix to create your normal design. This sounds like the progressive enhancement principle while we're going for graceful degradation.

Furthermore, we're only serving this style to IE people, not to everyone. Making use of the conditional comments would be way more difficult if we'd add a .js class instead of removing the .noJS class. Now we can use the .noJS as a selector prefix in a file added inside a conditional comment.

The method described above follows our objectives. While your method 'could' work it would become a very messy deal. Remember we're only making something for non-js IE users here. Start from there and it should all become clear :)

Thierry Koblentz

comment number
date
November 17, 2009 18:47

I'd agree with Chris on this, but I don't have time to expand. One thing I wanted to add though is that, as far as I know, adding a class to HTML is not kosher. I usually use an ID, because the class approach is too similar to the star HTML hack for my liking:

* html {}

Where there is no element above HTML

.noJS body {}

Where there is no element above body that can have a class

Thierry Koblentz

comment number
date
November 17, 2009 23:40

ooops! I see now that you're using BODY and not HTML, to set the "noJS" class. But then why not using HTML? That way you can turn that flag on or off directly from HEAD rather than BODY. Also, I believe it is better to set the hook rather than removing it. At least two reasons: 1. you do not pollute the markup. 2. this flag means nothing for the document, it is only relevant to the behavior layer.

I think it makes more sense to have rules in the styles sheet starting with ".JS" ('#JS' when using HTML) rather than ".noJS". Because default rules should assume that JS is off (and not the other way around). Or is it just a matter of preference?

Niels Matthijs

comment number
date
November 17, 2009 23:58

I believe, if you assume around 95% of your users have JavaScript enabled, that graceful degradation is a better option than progressive enhancement. You're only making an extra little effort for IE users without JavaScript in this case.

Remember I'm using this class specifically for IE users without javascript, so they'll receive a downgraded design when they have no support for html5 (= no javascript support).

I'm also having trouble trying to figure out how to go about styling the design using the JS class or id. You'd have to make the downgraded design for IE users as a base design, then upgrade it for IE users with JavaScript and upgrade it for all other browsers. Sounds very messy and overly complicated to me, but if you could further explain, please do. Maybe I'm just missing out on something :)

As for the html-element/id remark, I like the idea a lot. If it works fine I'll adapt the article right away!

Thierry Koblentz

comment number
date
November 18, 2009 07:41

Hi Niels,

For example, looking at your HTML 5 styles sheet for IE, I see that all rules (but the first one) apply only when JS is off, correct? So rather than using the flag "trick", why not using Javascript to remove the Conditional Comment that contains the styles sheet for IE?

Once that sheet is gone there will be no styling. For me, the advantage of this approach is that there is no need to pollute all documents with a class that relates only to the behavior layer and IE.

Also, not adding the "noJS" class prevents potential issue with the cascade as this extra class increases specificity (adds weight).

I don't know, I think it would make things simplier (cleaner?) and straightforward.

Niels Matthijs

comment number
date
November 18, 2009 08:32

Removing the css file with Javascript would work in this case, but if you use the #noJS for other elements (styling a carousel if there's no JavaScript) you'd have to place those styles in a separate css file too so they could be deleted if JavaScript is enabled. I don't really like that.

Of course you could argue that the styling for the non-JS carousel should be the base styling, but in such cases I'd rather work out a simplified model for the "exceptions". Also a lot easier when those exceptions become outdated. Simply remove the degrading styles rather than rework the base styles.

As for putting the id on the html tag, I already adapted it on this site, works like a charm! Many thanks for the valuable input.

mark rivera

comment number
date
November 18, 2009 23:59

one thing about html5 using some old yeah browsers... speaking of not ie6 or something but firefox 2.

i have virtual pc which have firefox 2 version and found out some annoying positions of my codes using html5 and kinda frustrated about the situation of the output. so i decide not to use the html5 codes anymore instead use default html5 and mixed of xhtml tags.

by this, i'd like to know if anyone have a better solutions on this? since i already use some techniques from google but no luck eh...

thanks people of sun!

* required fields

Leave your data
Leave a comment