Pages

Wednesday, May 11, 2011

HTML & CSS Tips: the box-model

I’ve been working with HTML and CSS for over a decade; however, like many I was never formally taught them and rather picked them up on the job. I’m also not sure how useful a course in HTML/CSS would be since the spec---and browser support for it---changes so frequently. But there are a handful of quirks and tips that if I had only known when I started I would have saved tremendous time tweaking scripts and pixel-perfect web designs. I would like to share some of those tips in a series of blog entries.


The first thing everyone must master when learning HTML is the box model. The box model describes the 4 areas that constitute an HTML element: margin, border, padding, and content. Here is the W3 spec on the box model.


I would like to highlight all of the things I found counterintuitive about the box model. First is the fact that the “traditional” box model---the box model you will use by default---measures width and height not from the edge of the box’s borders, but from inside content of that box. Why is this bad? Most people tend to think of a box’s dimensions as the amount of space it takes up, not how much space its contents takes up. This causes extreme frustration when you try to do something seemingly simple:


div.myContainer {
width: 200px;
}
div.myBox {
width: 100%;
border: 2px solid black;
padding: 0 10px;
}
<div class=”myContainer”><div class=”myBox”></div></div>

In the above example, one might think that myBox’s width will be 200px, given that its width is set to 100% of its parent. Wrong: it will be 224px wide and will overflow its parent’s space!

This is very bad for a great majority of web designs where we are trying to create an elegant look that integrates graphics and simple HTML structure. Often, the solution is to use wrapper elements or duplicate hard-coded width settings. But this complicates code and makes it harder to maintain.

Another emerging solution present in CSS3 is to use the box-sizing CSS attribute. This effectively allows you to specify what you mean when you set the width or height. It is well explained here. For example, see what happens if we add it to our previous example:


div.myBox {
width: 100%;
border: 2px solid black;
padding: 0 10px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}

Our example would now work as we originally intended! As it is written, box-sizing works in the majority of new browsers including IE8+ (do note the need to use -moz- for Firefox and -webkit- for Chrome & Safari).

The box-sizing attribute, combined with other emerging powerful tools like SASS and LESS (or .less in my usage), have finally given me the power to tame HTML and CSS documents and keep everything crisp and maintainable.

One final note: if you use the jQuery dimensions set of functionality you may find this quick-reference useful:


$('#foo').height(); // content height
$('#foo').innerHeight(); // padding height
$('#foo').outerHeight(); // border height
$('#foo').outerHeight(true); // margin height