Box Model & Layout

Margins, padding, borders, and display types

Understanding the CSS Box Model

Every element in CSS is represented as a rectangular box. The box model describes how the size of each element is calculated and how elements interact with each other. Understanding this is fundamental to mastering CSS layout.

Each box consists of four distinct areas, from inside out:

  1. Content: The actual text, images, or other content
  2. Padding: Clear space around the content, inside the border
  3. Border: A line that wraps around the padding and content
  4. Margin: Clear space around the border, separating from other elements

Visual Box Model Diagram

Margin (transparent, outside spacing)
Border (visible edge)
Padding (transparent, inside spacing)
Content (text, images, etc.)

Box Sizing: The Game Changer

By default, when you set width: 200px, you're only setting the content width. Padding and border are added on top of that width, making the total size unpredictable. This is called content-box.

❌ content-box (default)

Width: 200px
Padding: 20px
Border: 5px
Total: 250px!
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 5px;
/* Total width: 250px */

✓ border-box (better)

Width: 200px
Padding: 20px
Border: 5px
Total: 200px
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px;
/* Total width: 200px */

💡 Best Practice

Apply border-box to everything in your CSS reset:

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

The Display Property

The display property determines how an element behaves in the layout flow. It's one of the most important CSS properties.

display: block

Takes full available width, always starts on a new line. Width/height work as expected.

Block element 1
Block element 2
Block element 3
div, p, h1-h6, section { 
  display: block; 
}

display: inline

Only takes content width, flows with text. Width/height have no effect. Top/bottom margin ignored.

Inline 1 Inline 2 Inline 3
span, a, strong, em { 
  display: inline; 
}

display: inline-block

Flows inline but respects width/height. Best of both worlds.

Inline-block 1
Inline-block 2
Inline-block 3
.button {
  display: inline-block;
  width: 120px;
  height: 40px;
}

display: none vs visibility: hidden

display: none – Completely removed from layout

Element 1
Element 2 (display: none)
Element 3

visibility: hidden – Hidden but space remains

Element 1
Element 3
.hidden { 
  display: none; 
}

.invisible { 
  visibility: hidden; 
}

Margin & Padding

Margin creates space outside elements (between elements), while padding creates space inside elements (between content and border).

Margin (orange) pushes elements apart

Element with margin-bottom: 20px
Element with margin-top: 20px

Padding (green) creates inner space

Content with 30px padding around it

Shorthand Values

/* One value - all sides */
margin: 20px;

/* Two values - vertical | horizontal */
margin: 10px 20px;

/* Three values - top | horizontal | bottom */
margin: 10px 20px 30px;

/* Four values - top right bottom left (clockwise) */
margin: 10px 20px 30px 40px;

/* Individual sides */
margin-top: 10px;
margin-right: 20px;
margin-bottom: 30px;
margin-left: 40px;

💡 Centering with Auto Margins

Centered with margin: 0 auto
.centered {
  width: 600px;
  margin: 0 auto;  /* Top/bottom 0, left/right auto */
}

⚠️ Negative Margins

You can use negative margins to pull elements closer or even overlap them:

First element
Second element with margin-top: -20px
.overlap {
  margin-top: -20px;
}

Margin Collapse

One of CSS's most confusing behaviors: When two vertical margins meet, they don't add up—they collapse to the larger of the two. This ONLY happens with vertical margins (top/bottom), never horizontal (left/right).

Expected: 50px gap

margin-bottom: 20px
margin-top: 30px
20 + 30 = 50px?

Actually: 30px gap (collapsed!)

margin-bottom: 20px
margin-top: 30px
Result: max(20, 30) = 30px

Preventing Margin Collapse

/* Method 1: Use flexbox or grid */
.container {
  display: flex;
  flex-direction: column;
}

/* Method 2: Add border or padding */
.container {
  padding: 1px;
}

/* Method 3: Create new block formatting context */
.container {
  overflow: hidden;
}

Width & Height

Fixed vs Responsive Sizing

/* Fixed size - not responsive */
.box {
  width: 300px;
  height: 200px;
}

/* Responsive size */
.container {
  width: 100%;           /* Full width of parent */
  max-width: 1200px;     /* But never more than 1200px */
  min-width: 320px;      /* And never less than 320px */
}

/* Viewport units */
.hero {
  height: 100vh;  /* 100% of viewport height */
  width: 100vw;   /* 100% of viewport width */
}

/* Calculated values */
.sidebar {
  width: calc(100% - 250px);  /* Full width minus 250px */
}

/* Percentage heights require parent height */
.child {
  height: 50%;  /* Only works if parent has defined height */
}

⚠️ Common Gotchas

  • Inline elements ignore width/height: Change to inline-block or block
  • Inline elements ignore vertical margin: Use padding or change display
  • Percentage heights don't work: Parent must have a defined height
  • Margins collapse vertically: Use padding or flexbox to prevent
  • Default box-sizing is confusing: Always use border-box

✓ Quick Reference

  • Margin: Space outside, between elements (transparent)
  • Padding: Space inside, between content and border (transparent)
  • Border: Visible line around padding
  • Content: The actual stuff (text, images)
  • • Use border-box for predictable sizing
  • • Use Flexbox/Grid for modern layouts instead of fighting with display types