CSS lays out each element as one or more boxes. A basic box contains, from the inside outward, content, padding, border, and margin. Width calculations become predictable only after identifying which edge a declared size controls.
Content and Border Sizing #
The initial box-sizing value is content-box:
.card {
box-sizing: content-box;
width: 20rem;
padding: 1rem;
border: 0.25rem solid;
}The rendered border-box width is 22.5rem: 20 rem of content, 2 rem of
horizontal padding, and 0.5 rem of border.
border-box includes padding and border in the declared size:
.card {
box-sizing: border-box;
width: 20rem;
padding: 1rem;
border: 0.25rem solid;
}The content width becomes 17.5rem, while the border box remains 20 rem.
border-box is useful for components because adding padding does not make a
declared percentage or fixed width overflow its allocation.
Margins remain outside both sizing models and can still make the occupied area
wider than the declared size.
Apply Border-Box Sizing Consistently #
box-sizing is not inherited by default. An inherited reset lets components
override the root value when necessary:
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}Including pseudo-elements matters because decorative borders and generated content also create boxes.
Margins, Padding, and Overflow #
Padding belongs to the element and receives its background. Margin lies outside the border and remains transparent. Vertical margins between blocks in normal flow can collapse; padding, borders, flex layout, grid layout, and new block formatting contexts alter that behavior.
Margins do not collapse between flex or grid items, floats, absolutely positioned boxes, or across a block formatting context boundary. Parent and first- or last-child margins can collapse when no border, padding, inline content, clearance, or new formatting context separates them.
Percentage padding and margin resolve against the containing block’s inline
size, including vertical padding in horizontal writing modes. Prefer gap
inside flex and grid containers when spacing belongs to the layout rather than
to an individual item.
overflow governs content that exceeds the padding box:
.panel {
max-block-size: 24rem;
overflow: auto;
}Classic scrollbars consume space inside the border box. Overlay scrollbars do not, so avoid hard-coding a scrollbar width.
.panel {
scrollbar-gutter: stable;
}scrollbar-gutter can reserve room for a classic scrollbar and prevent a
layout shift when overflow begins. It has no visible gutter effect for overlay
scrollbars.
Intrinsic Sizes and Minimums #
Flex and grid items have automatic minimum sizes that can be derived from their min-content contribution. A long unbreakable token can therefore overflow a layout even when the track or flex item appears flexible. Permit shrinking explicitly:
.content {
min-inline-size: 0;
overflow-wrap: anywhere;
}Replaced elements such as images have intrinsic dimensions and aspect ratios. Constrain them without distortion:
img,
video {
display: block;
max-inline-size: 100%;
block-size: auto;
}Logical Properties #
Logical properties describe dimensions relative to the writing mode:
.notice {
inline-size: min(100%, 40rem);
padding-block: 1rem;
padding-inline: 1.5rem;
border-inline-start: 0.25rem solid currentColor;
}inline-size corresponds to width in horizontal writing modes, while
block-size corresponds to height. Logical properties preserve layout intent
for right-to-left text and vertical writing modes.
Browser measurement APIs expose different edges: clientWidth includes
padding, offsetWidth includes borders, and getBoundingClientRect() returns
the transformed border box. Select the API that matches the box under
discussion rather than compensating with fixed constants.
Comments
Read or comment on GitHub (sign-in required to comment)