Controlling width with CSS3 box-sizing

An incredibly useful CSS3 feature when you’re creating columns with floats is box-sizing. It lets you choose which box sizing model to use—whether or not an element’s width and height include padding and border or not.

This is useful since it makes it much easier to define flexible widths where you also need padding and/or borders. A typical example is laying out forms, which can be a real pain when you want flexible widths.

The box-sizing property takes two values:

A form layout example

I’ll use a form layout example to illustrate. Say you have the following HTML snippet:

<div class="group">
	<div class="text">
		<label for="text1">First name</label>
		<input type="text" name="text1" id="text1">
	</div>
	<div class="text">
		<label for="text2">Last name</label>
		<input type="text" name="text2" id="text2">
	</div>
</div>

Putting those two input + label combos (I’ll refer to these as columns from now on) on a single row is easily accomplished by floating them. But we also want the text fields to have a flexible width determined by the available width of their parents. This is to make them easy to drop into different layouts without having to fiddle about with calculating pixel widths.

Here’s some basic CSS to do that:

.text {
	width:49%;
	float:right;
	padding:1em;
	background:#fff;
}
.text:first-child {float:left;}
.text input {
	width:100%;
	padding:8px;
	border:2px solid #cce;
}

The problems

Simple enough, but there is a problem (two, actually) with this.

box-sizing to the rescue

And this is where the box-sizing property is so extremely handy. It solves these problems easily if we give it a value of border-box:

.text {
	box-sizing:border-box;
	width:49%;
	float:right;
	padding:1em;
	background:#fff;
}
.text:first-child {float:left;}
.text input {
	box-sizing:border-box;
	width:100%;
	padding:8px;
	border:2px solid #cce;
}

Now the widths of both the columns and the input fields will include their horizontal paddings and borders, resulting in a nice and flexible form row with no overlapping or dropped floats.

I’ve made a simple box-sizing demo page to show this in action.

Browser support and possible workarounds

As always when we’re talking about CSS, especially CSS3, there is the issue of browser support. It turns out that box-sizing is pretty well supported. A look at the support chart at When can I use… shows that the only relevant browser that doesn’t support it is IE 7. And that is highly ironic, since it does support the border-box model in quirks mode, as does IE 6.

To make all browsers obey you’ll need to back up the box-sizing property with a couple of vendor-prefixes, like this:

.text {
	-moz-box-sizing:border-box;
	-webkit-box-sizing:border-box;
	box-sizing:border-box;
}

And then there’s IE 7. Depending on the specifics of the layout problem you’re looking to solve, your target audience, and how far you and/or your client are willing to with respect to progressive enhancement, you may be able to just ignore it. In the case of form layout, the form will most likely still be usable, although it may look a bit ugly.

Assuming you want to do something for IE 7, there are a couple of options:

The demo page contains examples of both of these approaches. The box-sizing behavior is neat, but it seems to have issues with the units you use for padding (doesn’t like ems) and it has problems when one element with box-sizing:border-box is nested inside another. So in example 3, the box-sizing behavior is only applied to the column elements, not the input fields. To avoid the input fields becoming wider than their parents, I’ve made them a bit narrower for IE 7. Example 4 shows a possible workaround without using box-sizing. I’ve just reduced the widths of the columns and input fields to where they don’t become too wide until the browser window is really narrow.

View source on the demo page for HTML and CSS.

In closing, while box-sizing is well-supported, there is no solid support in IE 7 and earlier. Make sure to check that this lack of support doesn’t cause serious usability problems, and apply a bit of CSS band-aid if necessary.

Posted on April 5, 2011 in CSS