The way we are building web sites is fundamentally changing. The XHTML (Strict
if we took pride in our work) has given way to the more loose HTML5. Image slicing and dicing, and wrapper divs are starting to be replaced with lean (perhaps semantic if we’re lucky) HTML and CSS3 effects such as border-radius
, box-shadow
and gradients. Elastic layouts have metamorphosed into responsive design with Media Queries. JavaScript–no longer considered a toy–has earned its place at the table, forming a triumvirate with HTML and CSS. We may be at the cusp of a real tool for layout with flexbox. Perhaps even the venerable em
unit will fall out of favour, replaced with the more predictable rem
, and flexible vh
and vw
units.
As we stand in the foothills of the third major era of the open web (the age of tables and spacer gifs now all but a distant memory), our tools and processes are even growing up to start to resemble those of traditional programmers, with build scripts, preprocessors, linters (squint and it could resemble a compiler), automated testing, and version control.
But, it is something a bit more humble that I want to talk about today, which may also change how we write sites in its own little way. That is the CSS box-sizing
property.
Those of you who were around in the bad old days with remember the broken box model that IE used, rather than the standard W3C model. In this model the border
and padding
were counted as part of the width
and height
of the box. While in the W3C model the padding
and border
were added to the width
and height
to get the final dimensions of the box. In the IE model the width
represented the total width of the box, while in the W3C model it represented the width of the content box (that is the box that contains the content of the element). To get IE to play nice, we had to use Tantek’s box model hack.
The CSS box-sizing
property has existed for quite some time, and gives us a way to switch between the standard model (with box-sizing: content-box) and the old IE model (box-sizing: border-box). There has been a spark of interest recently in using this oft forgotten property, caused by Paul Irish’s * { box-sizing: border-box } FTW.
Time to switch to border-box?
If you want to get right to the action then please spend a few moments to take my poll on box-sizing, otherwise read on.
The standard will never switch to using border-box
by default, as too much content would break, but is it time to switch to using this for all elements in our own projects using the universal selector, as Paul advocates? Its something I’ve been giving a bit of thought to recently.
If it was just for my own personal projects, or on projects with a small team where I know the developers and can communicate it clearly, I think I would plump for it. But for use in a style guide meant to be used by many developers, and open source project, or demos that might be seen by many people I’ve never even interacted with, I’m still on the fence.
The pros and cons
There are certainly a number of well known developers in the pro camp. Paul Irish is certainly a fan. He sums up the frustration with the current model: Ugh. If I say the width is 200px, gosh darn it, it’s gonna be a 200px wide box even if I have 20px of padding.
Joe Lambert says I’m a big fan of this technique and have been using it in a number of mobile web apps (and increasingly) website projects
. Jeremy Keith simply calls it the bee’s knees
. While Stephanie Rewis wonders if we should have lobbied the W3C to change their box model instead. I hear this frustration from devs all the time.
.
Thierry Koblentz however has a word of caution:
Regarding what we used to call the “broken box model”, I think the issue is that you do not own the content box and any change in border or padding impacts that content area. I understand that it can be easier for people to style boxes that way, but it’s not a magic wand, you end up dealing with different issues.
Boris Zbarsky of Mozilla claims it [the spec] doesn’t define how it should work in enough detail that it can be implemented, leaving that to CSS3 Box, as far as I can tell…
, while David Baron (also of Mozilla, and the CSS WG) states box-sizing is a poorly-designed feature that’s frankly intended only for backwards-compatibility with quirks mode.
The pros and cons as I see it are the following:
Pros
- The size of an element is far easier to calculate. It is the size I tell it to be, no matter what I set the border or margin to be.
- We can use percentage based widths in a fluid design while still using
em
s or px for padding. With the traditional model we would needcalc
to solve this problem. See Chris Coyier’s excellent box-sizing post for an explanation of the issue. - If you have grey hair from all those days developing for IE, you already know how to use it.
Cons
- If you need to support IE7 and below it is a no go, unless you want to use a polyfill, or put IE into quirks mode (not a good idea). Firefox also still needs a prefix, and you’ll need the -webkit- prefix if you care about relatively modern versions of WebKit. See browser support.
- Firefox’s behaviour is still buggy, especially around interactions with min- and max-width/height.
- You lose control over the dimensions of the content box, which can lead to unpredictabilities you didn’t have to deal with before. For example, what happens if the padding is the same size or greater than the width or hight (cue frantic visits to the spec to check for the correct answer)?
- Perhaps the biggest issue for me is author expectation. If I use
* { box-sizing: border-box; }
on code that has to be used and extended by other developers, they will more often than not expect the W3C box model, and their own styles will not behave as desired. Furthermore, if they are a new developer, they might not be familiar with the IE box model at all, requiring further reading to get started even after figuring out the cause.
What do you think?
With all that being said, and plenty of other reasons in either camp that I’m sure you can come up with, what are your thoughts? If you were working on a project where other developers would need to work with your code, would you use box-sizing: border-box
? I’ve created a poll so that you can let me know, and when the results are in, I’ll report back with what the crowd voted.