← Back to CSS3 Mastery
Basic13 min read

Box Model & Layout

Understand how every element is rendered as a box with content, padding, border, and margin, and how display and positioning properties control layout flow.

The Box Model

Every rendered element is a rectangular box. The content area holds text and images, padding adds space inside the border, the border draws the edge, and margin creates space outside the border.

By default, width and height apply to the content box only. Setting box-sizing: border-box makes width include padding and border, which dramatically simplifies layout math.

  • Always set border-box globally — it is the modern default expectation
  • Margin collapse causes adjacent vertical margins to combine
  • Use logical properties (padding-inline, margin-block) for i18n-ready layouts
*, *::before, *::after {
  box-sizing: border-box;
}

.card {
  width: 320px;
  padding: 1.5rem;
  border: 1px solid #e2e8f0;
  margin: 1rem auto;
}

Display Types

The display property determines how an element participates in layout. Block elements stack vertically and take full width. Inline elements flow with text. Inline-block combines both — it sits in the text flow but accepts width and height.

Modern layouts rely on display: flex and display: grid, but understanding block and inline behavior is essential for debugging unexpected spacing and alignment issues.

.inline-badge {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  background: #fef3c7;
  border-radius: 4px;
}

.hidden { display: none; }
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

Positioning

Position controls how an element is placed relative to its normal flow. Static is the default. Relative offsets from the normal position without leaving the flow. Absolute removes the element from flow and positions it relative to the nearest positioned ancestor.

Fixed positions relative to the viewport, and sticky switches between relative and fixed when scrolling past a threshold. Always set top, right, bottom, or left when using non-static positioning.

  • Absolute positioning requires a positioned (non-static) parent
  • Sticky needs a scroll container and a top/bottom value to activate
  • Use inset shorthand instead of four separate offset properties
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
}

.sticky-nav {
  position: sticky;
  top: 0;
  z-index: 100;
}

Z-index and Stacking Contexts

Z-index controls stacking order within a stacking context. Only positioned elements (or flex/grid children) participate. Creating a new stacking context — via opacity, transform, filter, or isolation: isolate — resets z-index scope.

Debugging z-index issues usually means finding which ancestor created an unexpected stacking context. Use browser DevTools to inspect stacking order rather than blindly incrementing z-index values.

.dropdown {
  position: absolute;
  z-index: 50;
}

.modal {
  position: fixed;
  z-index: 100;
  isolation: isolate;
}

Overflow and Scrolling

The overflow property controls what happens when content exceeds its container. Hidden clips content, scroll adds scrollbars, and auto adds them only when needed. Overflow-x and overflow-y allow axis-specific control.

Overscroll-behavior prevents scroll chaining — where scrolling a nested panel also scrolls the page behind it. This is especially important for modals, drawers, and mobile interfaces.

.scroll-panel {
  max-height: 400px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

Get In Touch


Ready to discuss your next project? Drop me a message.