Course outline · 0% complete

0/30 lessons0%

Course overview →

display and box-sizing

lesson 5-2 · ~8 min · 15/30

Block and inline

Boxes are only half the story, since the page also needs rules for how boxes flow around each other. Without them every element would need hand-placed coordinates.

display is that rule, and misunderstanding it is why widths appear to do nothing on links and spans.

ValueFlowAccepts width and height
blocknew line, full available widthyes
inlinewithin a line of textno
inline-blockwithin a line of textyes
noneremoved from layoutnot applicable

h1, p, div, ul, and section are block by default. a, strong, and span, the inline cousin of div, are inline, and on them width, height, and top and bottom margins are ignored.

inline-block is the useful middle, flowing in the line while accepting width, height, and full padding:

a.button {
  display: inline-block;
  padding: 8px 16px;
}

display: none removes the element from the page entirely, taking up no space as if it had been deleted. JavaScript toggling elements in and out of display: none powers most show and hide behavior, as unit 8 shows.

Sizing the whole box

In lesson 5-1, width: 200px plus padding 16 and border 2 rendered 236px wide, because width only sized the content. That default, called content-box, makes layout math miserable.

border-box changes the deal, so width becomes the full box, meaning content plus padding plus border, and the content shrinks to fit.

* {
  box-sizing: border-box;
}
Modewidth sizes200px + 16 padding + 2 border renders
content-boxthe content only236px
border-boxthe whole box200px

With border-box, width: 200px; padding: 16px; border: 2px solid; renders exactly 200px wide and the content quietly becomes 164px.

Practically every real project puts this rule, with the * selector that targets everything, at the very top of the stylesheet. The capstone does the same.

width: 200px; padding: 16px; border: 2pxcontent-box, the defaultwidth sizes the inner box onlyborder-boxwidth sizes the whole box200renders 236164renders 200
The same three declarations under the two box-sizing modes: content-box adds the layers on, border-box carves them out.

Width under border-box

With box-sizing: border-box, width: 100px and padding: 10px render 100px wide.

border-box means the declared width is the rendered width, so the 10px of padding on each side is carved out of the inside and leaves 80px for content.

PiecePixels
declared width100
left padding10
right padding10
content80

The same declarations under content-box would render 120px. Nothing about the CSS changed except which layer width refers to.

Computing the leftover content room

Under border-box the declared width includes padding and border on both sides, so the room left for content is what remains after subtracting them.

function contentWidth(width, padding, border) {
  return width - 2 * padding - 2 * border;
}

console.log(contentWidth(200, 16, 2));
console.log(contentWidth(100, 10, 0));

Output

164
80
DeclaredPaddingBorderContent
200162164
10010080

This is lesson 5-1's totalWidth formula rearranged, subtracting instead of adding, so 200 − 2×16 − 2×2 = 164.

The pair of functions is the whole difference between the two box-sizing modes. One adds the layers to a content width, and the other carves them out of a declared width.

Hiding an element completely

The value that hides an element and removes the space it occupied is display: none.

The element is skipped entirely during layout, so it takes no space and behaves as if deleted from the page.

DeclarationPixels hiddenSpace kept
display: noneyesno
visibility: hiddenyesyes
opacity: 0yesyes

The distinction matters when toggling something in a layout, because visibility: hidden leaves an empty gap where the element was. Screen readers also skip display: none content, which is right for a collapsed menu and wrong for text meant to be read aloud.