May 12, 2008
I believe the recent surge in popularity of CSS frameworks comes from a lack of basic understanding of the CSS box model and how it’s implemented across browsers. I wanted to share with you some quick tips on how to avoid easy pitfalls so you can create your own CSS framework in no time flat, without all the cruft of having ten thousand column combinations available. Keeping these quick tips in mind at all times will allow you to do something I like to call defensive coding – and really that’s all CSS frameworks are: defensively coded snippets of CSS.
Here’s a super common pitfall: IE6 will double margins facing the direction of the float. Example problematic code:
This sidebar will have a 40px left margin in IE6 – almost certainly throwing the sidebar down below the content, and not next to the content as it should be. Easy fix: add display:inline;
No side effects in any browser, and IE6 obeys margins perfectly.
Why it works: By declaring float
on an element, you implicitly demand that it must be rendered as a block element – thus rendering the display:inline
inert. However, due to IE6’s awesome CSS engine, it fixes a bizarre bug that is the #2 reason I see CSS columns fail in IE6.
Let’s pretend you’ve got this simplistic setup of code:
HTML:
Harmless right? You might view this in Firefox and everything will be fine. But then you look at it in IE6 and your sidebar has mysteriously dissapeared below .main
. WTF? You look at the HTML, the CSS, and everything’s fine. What could possibly be wrong? A common problem here is if awesome.gif
is 510px wide. What this does is push out .main
to 510px, and suddenly there’s not enough room for .sidebar
inside .columns
any longer. Ack!
Easy fix: add overflow:hidden
to your columns. This forces the width restriction to crop any extruding content. New magical CSS:
So you’re building out a simple product listing template out, and you throw it in an unordered list:
HTML:
This CSS will work just fine in something like Firefox, but for mysterious reasons you’ll see that Product #4 appears on it’s own line in IE6. What’s happening here? I mean 4 columns x 85px + 3 gaps x 20px = 400px, right? Except that your 4th gap is hanging over the right edge – pushing the true width of the blocks to 420px. Firefox is smart and lets that margin just hang out there – but IE6 will apply that margin within the parent wrapper – throwing the 4th item down since it takes up 20px more than it should have.
The fix? Apply a left margin to each item, with a negative margin to the wrapper. This means that every item has a visible margin, but the whole block of elements are yanked back by the negative margin:
This gets around the nasty solution of adding a class to the first or last item in every row – something I’ve seen with abundance around the web.
Wev’e got to start out with some basic HTML. Here’s what I’ve been using lately:
For different column widths, I’ve been changing out the col2
declaration to things like col2A, col2B, col2C
and so on. You could easily give them more semantic names like products-columns
too.
The first step for any column framework is self-clearing. It’s easy, practical, and reduces all those damn clearing divs.
Next step is to actually float those columns. So let’s add a couple more declarations:
Oh, yeah. That’s it. That’s all it takes to create reliable columns in CSS. Really.
Here’s an example page to prove it!
If you'd like to keep in touch, I tweet @kneath on Twitter. You're also welcome to send a polite email to kyle@warpspire.com. I don't always get the chance to respond, but email is always the best way to get in touch.