Box Sizing

The layers of margin, border, and padding enclose the box holding an element's content. The size of this box is determined by the width and height properties. The story of how this box is sized is not simple, however, so let's examine some of the factors that influence the calculation.

By default, both width and height are set to auto. What exactly auto means depends on the context. For a block element, a width of auto means that the element will fill its parent, much like it would if set to 100%. For an inline element, a width of auto means that an element is sized around its content. For both kinds of elements, a height of auto means that an element is sized around its content.

Leaving the dimensions at auto is a reasonable default choice, given that the size of the child content can be hard to predict because it depends on the viewer's font preferences, window size, and zoom level. If you fix the size of a box, the content may flow outside its bounds, as it does on this button:

html
css
preview

The width may have seemed fine before the button was localized to Spanish.

The button's height is tailored nicely thanks to auto. But the width is too small, creating overflow. Switching the width to auto doesn't yield a satisfying button:

html
css
preview

The button expands to fill the panel because it's a block element. If it's bad to fix an element's width when you can't predict the size of its content, must you then make an unpredictable element fill the page? No. There are several solutions, and you'll read about one of them in the next section on the types of blocks. Another solution is to use a different layout system, like Flexbox, which you'll read about later. The message for right now is to avoid fixing an element's size unless you can be certain about the size of its content.

Check out this nice box that is sized to horizontally fill its parent:

html
css
preview

The box fits so well. Try using your browser's inspector tool to figure out the box's width in pixels.

How well does it fit its parent when you add a border?

html
css
preview

It no longer fits the parent. The box is wider and causes overflow, with leads to horizontal scrolling. Horizontal scrolling is a frowned upon on the web. Try using your browser's inspector tools to determine the box's width now. Do you see why the box is overflowing its parent?

What happened is that the width of 100% was applied to the content box, and then the border was tacked on as an addition, which caused the element's overall dimensions to exceed the width of the page. You could try to fix this by subtracting off the width of the border from 100%. CSS does provide a calc function that supports this, but there's a better way.

You can tell the browser which box you are sizing using the box-sizing property. Its default value is content-box. Watch what happens when you switch it to border-box:

html
css
preview

With border-box, you are describing the size of the element's overall footprint. The content box is shrunk accordingly to fit inside the border. This kind of sizing is arguably far more useful for laying out your page than the default. Nevertheless, you will need to explicitly switch the box-sizing property to get this superior behavior. Some web developers include this wildcard ruleset:

* {
box-sizing: border-box;
}

If an element has no padding or border, then the content box and border box have the same dimensions, making the box-sizing property irrelevant.