Defensive coding and CSS: Preventing the most common bugs

This is the first installment in the Defensive coding and CSS series. I’ll be dealing with the most common CSS bugs and showing you how to avoid them by slightly changing your coding style.

In this first installment I’ll be covering these issues: CSS resets, clearing floats, double-margin, hasLayout, and #id.class bug. These are the bugs that, in my experience, happen the most often and sometimes cause other, more serious bugs.

Defensive coding is about preventing these bugs before they happen. If you don’t prevent them, they will be like an avalanche — there will be a lot of them interacting with each other, making it difficult to figure out what’s what.

CSS Resets

When I began coding with CSS many years ago, I didn’t know any good CSS resets; in fact, there were none back then. The difference in default styling of elements between browsers can cause margins, paddings, line-heights, and even some alignments to be completely different. That’s why I started using the * {margin: 0; padding: 0;} declaration to battle those bugs.

About three years ago I discovered that this approach was inefficient; not only that, it was also messing up my forms and causing all kinds of havoc. Since then, I’ve been using the popular CSS reset by Eric Meyer.

Eventually I decided to modify it and extend the reset to serve my purpose better. I created the aardvark.legs CSS framework, which unifies the styling amongst all the popular browsers. This has proved to be a real time saver, because now I don’t have to spend as much time dealing with inconsistencies between browsers.

Clearing floats

I think everyone will agree that uncleared floats are often the cause of major bugs, especially in IE6. However, it’s a bug that is easy to fix. My favorite method is setting overflow: hidden; for the parent element containing the floats and then using conditional comments or hacks for IE6 to declare overflow: visible; height: 1%;. This ensures reliable cross-browser rendering and prevents any possible bugs associated with overflow: hidden; in IE6.

Dealing with double-margins in IE6

IE6 has another annoying bug when it comes to floats, called double-margin. It occurs when you float any element in IE6 and add a margin to it. Under these circumstances, IE6 decides to double the margin set and puts your element somewhere it shouldn’t be. This is easy to fix, and I’m always surprised that people don’t prevent this one before it happens.

The easiest way to avoid the double-margin bug is to set display: inline; on any element that you float. This way you will never have to see or worry about the bug again.

Dealing with hasLayout and its consequences

If you haven’t heard of the hasLayout term before, I recommend you read this useful article on it. If you have, read on.

The problem with hasLayout comes up quite often in coding. One of the most annoying variations of the bug is trying to use position: absolute; bottom: 0; and having the element appear somewhere completely different in IE6. The issue is, fortunately, easy to solve — you need to trigger hasLayout. This can be done in many different ways. My favorite is using conditional comments or IE6 hacks to set height: 1%. While there are other ways to give something a layout, this is by far the least problematic one, in my experience.

Again, it doesn’t hurt to think of it ahead of time. Whenever you add bottom: x; to your CSS, think of whether the container hasLayout or not. This way you will prevent the bug before it happens and won’t have to spend the extra time debugging.

The ID + multi-class bug

This is a bug that never got a name, or at least none that I can remember. It’s a peculiar beast and happens only in IE6 when you have this kind of code: #id, #id.class2, #id.class3. The first definition will be applied, but the other two won’t. The simplest way to avoid it is to not use the #id at all. Sometimes you need to take advantage of the cascade; in these situations, I recommend using #id, #wrapper .class2, #wrapper .class3. The two rules are more specific than just #id and at the same time don’t suffer from any bugs in IE6.

Don’t fix, prevent

Ultimately, this is not about the techniques; it’s about preventing the bugs rather than fixing them. If I was a proficient mathematician, I could probably give you some formula that would determine how much more time is spent on fixing a bug vs. preventing it. Since I’m not, you’ll just have to trust me…

Leave a Reply

Your email address will not be published. Required fields are marked *