Grow your CSS skills. Land your dream job.

International box-sizing Awareness Day

Published by Chris Coyier

It's February 1st today, which I've decided to declare International box-sizing Awareness Day. In honor of, you guessed it, the most humble and undersung, yet awesome and useful CSS property: box-sizing.

The date corresponds to Paul Irish's post where he introduced the concept of using it on every single element on the page. We've talked about it around here a few times as well.

Here it is, in all it's glory:

*, *:before, *:after {
  -webkit-box-sizing: border-box; 
  -moz-box-sizing: border-box; 
  box-sizing: border-box;
}

The default value for box-sizing is content-box, which is what we are overriding here. There is also a padding-box value but... kinda useless if you ask me. We'll get to what this means shortly.

Notice we're using the * selector to select all elements, as well as making pseudo elements use the same model, which otherwise wouldn't be selected by the * selector alone.

Here's the browser support situation. "-" = "this version and down". "+" = "this version and up".

*, *:before, *:after {
  /* Chrome 9-, Safari 5-, iOS 4.2-, Android 3-, Blackberry 7- */
  -webkit-box-sizing: border-box; 

  /* Firefox (desktop or Android) 28- */
  -moz-box-sizing: border-box;

  /* Firefox 29+, IE 8+, Chrome 10+, Safari 5.1+, Opera 9.5+, iOS 5+, Opera Mini Anything, Blackberry 10+, Android 4+ */
  box-sizing: border-box;
}

In the fairly near future we won't need any prefixes at all for it, but I like to just leave that kind of thing to Autoprefixer.

Why all the HOO-RAH?!

It makes working with boxes so super duper much nicer.

When you set the width of an element, that's the width that it is. If you set the width to 25%, it will take up 1/4 of the horizontal space available in its parent element. That's it.

That's not always the case. With the default box-sizing, as soon as an element has either padding or border applied, the actual rendered width is wider than the width you set.

Actual width = width + border-left + border-right + padding-left + padding-right

The math is bad enough, but when combined with percentages (or any mixed units, really) the result is impossible to do in your head and, more importantly, ends up being some useless number that you can't do anything with.

You might think of it this way: with box-sizing: border-box the padding and border press their way inside the box rather than expand the box. The result is a box the exact width you set it to be and can count on.

Columns is a particularly useful case, but this comes in useful all the time and becomes one of those things that just makes CSS development better.


Remember to read Paul's original post which covers some more ground like performance (don't worry about it), jQuery (don't worry about it), and third-party content (easy to fix).

Happy International box-sizing Awareness Day! Maybe next year we can get organized about it and all wear groovy square sunglasses or something.

Comments

  1. I love this. I have been using it for a while now and it is one of my favourite parts of CSS. Create a little sass mixin and you don’t even have to remember all the prefixes.

    @mixin box-sizing {
        box-sizing: border-box;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
    }
    

    Then @include box-sizing;

    This is more useful if you don’t need to apply it to EVERYTHING that is included on the page the stylesheet is linked to.

    • That totally works! Just a few notes…

      • If you’re using Compass, it includes that mixin and it’s named and outputs exactly that
      • My rule of thumb is to @extend things things rather than using a @mixin with no params (longer selector is less code than multiple repeated properties)
      • I recommend moving away from using either @mixin or @extend for prefixing and into something that updates itself over times, like Autoprefixer
      • If you find yourself using this a lot, consider using the universal selector for it.
    • Or just use a pre-processor that does the prefixing for you, helps keep your code clean! I recommend Prepros.

    • @chris I had no idea that Compaass had a mixin for it. Probably should spend some time looking into what they provide. I have only used the transition and transform mixins.

      I also need to look into the @extend property more, it seems awesome!

      I am having some issues getting Autoprefixer working with CodeKit. I’ll keep playing with it.

      Thanks Chris! :)

    • I’m with Chris on this one. The universal selector is very apropos for box-sizing, especially with responsive design making layouts all percentish and what not.

    • what use will a mixin be if it doesn’t have to be repeated. I find mixins most useful if it’s a property I need to use severally and requires vendor prefixes. The wildcard * can just handle it all as shown earlier in the article
      *,*:before,*:after{box-sizing: border-box;}

  2. Border-box is nice but content-box is still useful. Here is a useful case: You want an element to be a fluid container that is centered and doesn’t grow more than 1000px and still has padding if the browser window is smaller than 1000px.

    .container {
      display: block;
      box-sizing: content-box;
      margin: 0 auto;
      max-width: 1000px;
      padding: 0 2%;
    }
    
    • Not sure I totally follow. Simple demo. How does box-sizing affect your ability to do that?

    • It’s just nice to be able to switch between the two. In my example, padding is acting like a second margin since I’m using margin to center my container.

      In my case I want a container to put elements in that doesn’t grow larger than exactly 1000px. Since I want to use a percentage gap on the sides it is more difficult to use border-box so that my inside area doesn’t grow larger than 1000px.

      Here is an example of doing the same thing as the content-box example above only using border-box.

      I had to use calc to add the padding to the max-width. Now measure the P element inside the DIV when you stretch your browser wider than 1048px, it is exactly 1000px.

  3. Permalink to comment#

    When I first started to explore HTML and CSS ten years ago I was a child (~12yo) and used to try with IE on Windows ME (yeah, you’re laughing, I know). :D

    Then I discovered “normal” CSS stuff (with Firefox) and started to learn the true box model. The only thing I’ve always missed about IE was it’s wrong interpretation of the model (I mean, IE6 used to do everything as per border-box). When border-box came out, I was so glad my idea of "width: 100%" was available again. :)

    • IE6 used to do everything as per border-box

      Just to be clear, that’s a slight misconception. PRE IE 6 was like that, but IE 6 was the normal box model except when in quirks mode, which was triggered by stuff like an incorrect or missing DOCTYPE.

      This WikiPedia article explains it pretty well.

  4. Dustin Horton
    Permalink to comment#

    Traditionally it’s been advised to use a more robust reset like Eric Meyer’s for performance reasons.

    If you’re already using the universal selector to apply box-sizing, is there any reason to not use that same declaration for your reset?

    * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }
    
    • That’s my go-to reset.

    • ewfwege
      Permalink to comment#

      you should switch to normalize. universal resets are so oldschool.

    • Dustin Horton
      Permalink to comment#

      Nothing ‘old-school’ about it. Different concept with different goals. Personal preference.

    • Personal preference, yes. However, “traditionally” universal resets are indeed “old school.” There is nothing wrong with “old school” approaches as long as they still work, but you’ll likely see more use of normalize in the future as normalize is a more finely-tuned approach which doesn’t require a lot of extra manual effort.

      In the end, it could be argued that normalize is a more DRY approach. Of course, normalize is only a guideline. Each person can have their own “normalize” routine and preprocessors are doing a good job lately of allowing this kind of customization.

  5. MaxArt
    Permalink to comment#

    The standard box model is one of the worst mistakes that the W3C has ever made.
    Microsoft was, once in a while, correct thinking that designers wanted to size the container, not the content.

    As a result, IE6-7 doesn’t even support border-box sizing (natively – there are workarounds with CSS expressions) unless in quirks mode, that nobody ever should use. Ever.

  6. Scott
    Permalink to comment#

    Here’s hoping next year will be International FlexBox Awareness Day.

  7. JJohnson
    Permalink to comment#

    I wish I had even known about resizing this way. I have to do so many nested elements to achieve this – going to really clean up some of my code.

  8. Being a baby-faced web designer has its perks; since I starting learning CSS a year ago, I’ve never had to use the older box-sizing value due to solid browser support across the board. It made learning float-based layout much, much easier and fought off loads of potential frustration.

    Bootstrap 3 and Foundation 5 both use box-sizing: border-box on every element by default nowadays. Pretty much cements it as a best practice in my mind.

  9. ewfwege
    Permalink to comment#

    i wonder, if mozilla is ever going to drop the prefix. there have been discussions about dropping it since 2004(!): https://bugzilla.mozilla.org/show_bug.cgi?id=243412

  10. Awesome post! I’ve read several blog posts and read about box-sizing:border-box but I actually created a CodePen this evening after reading this article. It’s pretty freakin’ sweet!

  11. Jack
    Permalink to comment#

    I remember when I was first learning html/css about a few years ago, I had no idea about border-box or calc. To make a box to fill a certain percentage of the page AND have a border was close to impossible, you either had to do really weird things with the html/css, not use borders, or use JavaScript, which I wasn’t very good at at the time. I am so glad this property exists, it’s so much more intuitive.

  12. Permalink to comment#

    After I getting learnt with box-sizing
    border-box.But, silly argument I got from old designers (who still follow
    table tr td
    is it is very hard to size the layout seperately to IE-6/6- versions. So, it is better to go for! content-box for all content rather than resets.!
    “—“But, i thought its right for the guys to go with content-box who copies PSD web template as it is with photoshop slicers!

  13. I happened upon the awesome benefit of this code snippet just days before Paul published his original post and have been using it ever since.

    As MaxArt mentions above this CSS is not supported by IE6 and IE7 which probably isn’t a problem for most people.

    I had to support IE7 on a project when I was still using LESS. So I wrote up this simple little mixin on CodePen to create a fallback for IE6-7 by using a conditional class added to the HTML.

    I’m now using Sass, and have been mid 2012 so I decided to recreate that mixin using Sass which I’ve also got on CodePen.

    I also wrote up how it works on my blog late last year.

    That mixin is also included in my little Sass library – Sassifaction

  14. Mary
    Permalink to comment#

    Indeed a BIG HOORAY! All that fuzzing with percentages all the time is now history! Thanks!!!

  15. *, *:before, *:after

    Star (*) before pseudoelement name is unneeded. *, :before, :after is sufficient.

    By the way, at the time of Paul’s writing, box-sizing could not yet actually be used globally since Firefox had a bug resulting in incorrect calculation of min-height/max-height when used in conjunction with box-sizing: border-box. Since then, the bug has been fixed in Firefox 17 released on November 2012, and now default box-sizing: border-box can indeed be used.

    • True on the selector naming! The star essentially stands for “any element” which is what not saying anything stands for. Just like *.class is the same as .class, even in terms of specificity since * has none. (test case).

      Nice reminder of that min- max- saga too. I’m not sure it would have made it unusable, but it was certainly something that needed attention.

  16. Until recently I only really used it to make responsive forms behave properly and I was a bit shocked when someone at work suggested using it globally. Now it’s included as part of my reset in every project.

  17. Permalink to comment#

    Beautiful! I never knew! This is going to make life so much easier. Thanks Chris!

  18. Harry Clarke
    Permalink to comment#

    I’m really new to the whole ‘web development’ thing, and to be honest this whole thing seems so much harder than it needs to be; this little trick has definitely made my web development career so much easier. Thank you so much.

  19. Permalink to comment#

    I used JavaScript in some projects to fix these kinds of problems and nested divs inside divs to override content going outside bounds. Thanks for this info! It’s very useful for me! ;)

  20. Permalink to comment#

    I try to make every day International Box-Sizing Day. I can’t sing its praises enough. Every time I’m given a layout to fix from one of the designers at work, adding it is the first fix I make. Viola, stuff aligns.

  21. Matthew
    Permalink to comment#

    Why am I not using box-sizing?!

  22. SZRImaging
    Permalink to comment#

    I personally hate resets, but this is one snippet of code I apply to everything first. And since I have started using it, I have had a fraction of the cross-browser issues. It has probably saved me hundreds of hours in trouble shooting IE vs everyone else.

  23. Permalink to comment#

    Once again, all I have to do is casually come to this site and I learn something super useful. Thanks Chris (and originally Paul)!

  24. Mark
    Permalink to comment#

    I’m surprised folks haven’t heard of this beforeā€¦ that alone is blowing my mind.

    • Agreed! Good reason for someone with the wide-spanning audience Chris has to continue to blog about these things. Sometimes we’re focusing so much on the future and the now that we forget how challenging it can be to keep up. Sometimes getting sucked into a project for 6 months where you have no time to keep up means you miss important things like this.

  25. Am I the only one who prefers leaving the browser default content-box and only apply border-box when needed? Then I don’t need to set back to content-box in my CSS whenever that makes sense to use. Both box models make sense in certain situations, and on most elements on a page they make no difference.

    Anyway it just feels cleaner to me only to apply border-box where needed, no big deal if people prefer otherwise.

    • I know where you’re coming from, but once you switch to a universal selector, you find all kinds of places where it has come in handy. Especially true with anything responsive.

      Since there are very few side effects, it’s one less thing to calculate. It just works.

  26. Mike DeSart
    Permalink to comment#

    Border Box is my best friend in CSS land.

  27. I still die a little inside every time I realize “Gee, the IE6 honestly had it right with the box model.”

    Regardless, it’s the truth.

    • fsdf
      Permalink to comment#

      why? at the time ie6 was the best and most modern browser by a long shot.

    • Permalink to comment#

      It wasn’t IE6, it was IE5.5 and earlier. IE6 only did this in quirks mode (which I believe was by design, to be backwards compatible with the IE5.5 box model). IE6 rendered the box model just fine, aside from some (admittedly major) float/margin bugs and other layout issues.

    • Nothing was wrong with IE6 when it came out. It was far ahead of the rest of the browsers when it came out. It’s just that they stopped innovating until the monopoly was threatened.

  28. This is going to make my life so much easier. Thanks Chris!

  29. Melanie Sumner
    Permalink to comment#

    This snippet is in my default css without a doubt. Finally someone is raising awareness for something I actually care about! (tongue in cheek, perhaps, but still)

  30. Tom
    Permalink to comment#

    Thank you, I had no idea this even existed….thank you.

  31. Thanks Chris for sharing this important article. I have faced this issue few weeks ago when one of my client needs 300px width fixed box and after i have applied border and padding to that box, i noticed that the width of box in exceeding from 300px. Further inspecting it in Firebug layout i calculate width with formula you mentioned above its 305px. Now its good to use box-sizing rather then calculating widths. Thanks

  32. Someone should notify CSSLint, I dont use the program due to it hating the use of the global element to style anything, and I am not going to go and load up a reset file for each known possibly unknown HTML element. I really enjoy linting tools I just wish amazing fixes like this one made it into that one.

  33. Michael
    Permalink to comment#

    I love box-sizing.

    I found I would always add it to so many elements, then found out about the select or elements method ( * )

    I will admit, it did cause me a headache when one element just wasn’t working properly, it was because of the box-sizing. But once I understood what was the cause, it was an easy fix ( Might have been on the container etc ).

    So I prefer selecting all, and making the one modification to fix a little issue.

  34. Ben
    Permalink to comment#

    I’ve wondered if I should do this – now I will!

    Excuse my ignorance but I can’t work out why you need the before and after pseudo elements?

  35. cssJumper95
    Permalink to comment#

    Whoa!!! I av been seeing this for a while but I neva bothered to find out what it means. now that I know what it does I will use it all the time. Thanks

  36. Anthuan Vasquez
    Permalink to comment#

    Sass + Compass

    *, 
    *:before,
    *:after {
        @include box-sizing(border-box);
    }
  37. Simon Dell

    A project I’m working used the global and pseudo-selectors approach. One of our significant layout elements completely failed to render properly in Firefox, of all browsers. It took me ages to work out the fix (simply specifying width: 100%: which you’d think was unnecessary). For far too long it looked like a rendering problem caused by the global box-sizing: border-box;.

    I think I’m alone in disliking the global approach. Sorry Chris (and sorry Paul Irish who’s got a similar posting). I appreciate the frustration the content-box model causes (I’ve suffered that pain too), but i feel the problems it causes only arise on a handful of containers per page. To me this doesn’t justify using a global selector that radically changes the layout model of the entire page.

  38. Nick Toye

    I’m finding that this doesn’t work for Button element.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".