Cross-browser CSS and JavaScript

What we do with browsers in most cases? We get frustrated by browser incompatibilities, differences, anomalies and the like. But why so? Is it browser's fault? In most cases, it's our fault because we don't know how browsers work when it comes to CSS and JavaScript. We have precooked ideas about browsers and we can't get rid of our prejudices. Of course, browsers have their faults and bugs, but it's up to browser implementors to fix them. Our job is to provide feedback to browser implementors to help them with building better applications. Now let's see how to write cross-browser CSS and JavaScript.

Browsers interpret specifications, developers use them

This is the first key concept to grasp. We write CSS and JavaScript often without knowing exactly what lies underneath the surface. On the contrary, browser implementors know all the nuts and bolts of the ECMA and CSS specifications and, what's more, they have to interpret them. That's because a specification explains how a standard should work in theory, not how it works in a practical implementation such as a web browser. For example, in the CSS specifications is not explained how to contain floats. We all use overflow: hidden and that works, but this is not covered by the CSS specifications. CSS specs only say how to clear floats. And that's all.

In JavaScript, we all know the several different patterns for handling inheritance (e.g. those by Douglas Crockford), but in the ECMA specifications only the basic prototypal pattern is explained, all contained in a single paragraph with only a single figure! After this paragraph, nothing more is said about inheritance. So everything we use today is the result of years of testing, ideas, examples and daily use of standards. In a word: experience. Experience against theory.

Keep it simple

Three weeks ago a client asked if it were possible to have a former Flash site with animations entirely rebuilt with HTML, CSS and JavaScript. Yes, it's possible, but I have to say that after viewing the Flash site I was quite anxious. So I focused on all components, divided them into simpler ones and then started coding following this order:

  1. HTML: structure
  2. CSS: presentation
  3. JavaScript: behavior

I focused first on CSS, testing everything on Internet Explorer and Firefox first and then in the other browsers. I noticed an overflow problem on the page occurring in IE 7 and 6, so I copied my template in another folder and started testing only in these browsers. My main container was as wide as the whole page, so I tried an overflow-x: hidden on this element but I didn't work. So I tried body, but it didn't work. It was actually the html element that was causing the problem, so I moved the CSS rule in a separate file called iefix.css and linked it through conditional comments.

For the JavaScript component, my choice is always jQuery. The animations used in the original site were actually divided into two groups:

  1. repeated animations
  2. simple animations

For the former group, I decided to use JavaScript timers, for the latter, instead, only single calls to the animate() method. I always follow an OOP approach but before using objects I need to get an overview of the various actions that I'll wrap in objects. So I used the classical procedural approach first:

$(document).ready(function() {

   first();
   second();
   
   // other functions

});

All versions of IE returned the same error saying that they were unable to get the correct value of the visibility property. I checked out the line of code reported as an error and I found out that I was using visibility: 'hide' on the animate() method. So I asked myself: is there another way to hide an element? Yes, opacity: '0', so I tried this approach and it worked.

Then I wrote my objects, wrapping all my functions one by one and turning my variables into object properties. Every time I double-checked if the newly inserted method worked ok, and then moved to the next. They worked. After a week of work, the template was ready, fully operative.

So the golden rule is: keep everything simple, divide tasks into smaller ones and test them one by one. Finally, assembly everything.

Reuse your code

If something works, why change it? If you have some components of your CSS and JavaScript code that work on every site you've developed, then it's time to save them in your template folder and use them on your projects with minor changes. If your code is standard and works now, it's highly likely that will work in the future. So select your components, divide them into sub-components and reuse them as templates.

Test, test and test again

If you have to do something new, the best thing to do is testing the new feature before adding it to your code. Lately I had to use the JSAnim library. Since I use jQuery, I wanted to be sure to get it right before using it in my code. So I checked out the examples to see how this library works. I found out that I could actually combine JSAnim animations with jQuery animations, but also that IE failed when it was forced to use animate() after a chain of JSAnim animations. I saved everything on a test page, and I wrote down a note saying "JSAnim animations work better alone. This test will spare me a lot of time when I'll have to use this library on a live site. So test before doing anything. And test again.

Leave a Reply

Note: Only a member of this blog may post a comment.