CSS3, HTML5 and how to degrade gracefully.

How we managed to use some HTML5/CSS3 sugar in our website while mantaining legacy browser compatibility.

Update 02/23/2011: I forgot to mention how to use the new HTML5 tags in a way that works in Internet Explorer. Added a section accordingly below! Also added a link to the fabulous Modernizr library.

Every time we start a new application layout face the same question: should we support older browsers? Can we use the sweetness of CSS3 and HTML5 or should we stick to legacy code?

In our website we're using some techniques that allow us to use some of it while mantaining backwards compatibility and, sometimes, simply gracefully degrading.

New html5 tags

Something that most people forgot about HTML5 is that, above all the new bells'n'whistles, is meant to make the web more semantic. That is, when google or any other scrape sees your website, it's easier to look for the relevant information (like articles in a blog) or separate the main content from a side comment.

If you look at the code of your website you'll see that we're using tags like <section>, <article> and <aside> all the time. If you wanna learn the details, you should read the w3schools html5 documentation.

The important trick i wanted to explain here is how to make Explorer aware of these new tags. In short: Use the HTML5 Shiv Javascript Library that shakes some IE bugs to make it recognise the new tags as they were normal divs :).

Buttons

Have you noticed how beatiful are the buttons we use in our website? Well, if you don't... You seriously need to update your browser.

We've created a SASS mixin based on Ubuwaits' CSS3 buttons repo.

You can check out the actual code if you want.

As you can see, we've added sass variables so it will automatically generate all the colors of gradients, shadows, etc using the base color.

The sweet thing is that it will degrade no matter what browser you use. If your customer is using Explorer 6, he probably won't notice there's a shadow missing :)

CSS3 transitions

We added some effects using CSS3 transitions in our services page. They don't work on any browser that's not webkit-based but hey! What's the problem? It isn't unobtrusive and adds some extra dynamism to our site.

The code we used is simple, and as always, you can see it in our repo. Notice that we're using compass.

# app/stylesheets/_services.sass
article img  
  +transition(all, 0.8s, ease-in-out)
  -webkit-opacity: 0.7
article:hover  
  img
    +transition(all, 0.8s, ease-out)
    -webkit-opacity: 1
article#webapplication  
  img
  &:hover img
    margin-top: -15px  
    margin-bottom: 15px
article#kickstart  
  img
    -webkit-transform:  rotateZ(0deg) rotateY(0deg)
  &:hover img
    -webkit-transform:  rotateZ(20deg) rotateY(0deg)
article#training  
  img
    -webkit-transform:  rotateX(0deg) rotateY(0deg)
  &:hover img
    -webkit-transform:  rotateX(360deg) rotateY(0deg)
article#rescuemission  
  img
    -webkit-transform:  rotateZ(0deg)
    +transition(all, 0.8s, ease-in-out)
  &:hover img
    -webkit-transform:  rotateZ(180deg) 

How could i know if a particular css3 property is supported?

Use Modernizr. It adds classes to the html element of your page so you can use css3 properties when needed and change their behavior if they're not supported :).

pushState and replaceState

Our work page makes use of HTML5 history.pushState() and history.replaceState() to allow the user to use the back and next buttons on the browser to go back and forth on the slides while we're also changing the URL. To achieve this, we're using balupton's history.js.

Again, since any browser other than webkit supports history.pushState (which allows changing the actual url shown in the browser through javascript), history.js falls back to the anchor syntax (#) when the function isn't available.

The result is that you will see some nice transitions when switching from project to project, and you're still able to go back and forward or share a link to a particular project using the URL.

Check it out:

Form placeholders

Since we like HTML5 placeholders (labels are hard to style and waste a lot of space!) we've decided to use the same approach as the previous case: use the native ones when supported, while using javascript in other cases.

You can see it in our contact form. This time, our choice was andrewrjones' jquery-placeholder-plugin.

Do you know any other similar techniques that help us get closer to HTML5/CSS and jump over the gap between modern and older browsers? Feel free to share it!