Skip to main content

Wait, Why Does My Width Stay 384px But Height Changes? Understanding the CSS Box Model

Β· 9 min read
Mahmut Salman
Software Developer

I'm a backend developer learning frontend, and I just noticed something weird in Firefox Inspector. I removed p-8 from my div, and the height changed from 124px to 60pxβ€”but the width stayed at 384px! πŸ€” My frontend mentor explained the CSS Box Model and why w-96 behaves differently from h-auto. This conversation finally made the box model click for me.

The Mysterious Dimension Change​

Me (Backend Dev): I'm looking at this div in Firefox Inspector:

<div class="bg-white w-96 h-auto p-8 rounded-lg shadow-lg border-2 border-black">
<h2 class="text-2xl font-bold text-center mb-6 text-gray-800">Welcome Back</h2>
</div>

With p-8: Inspector shows 384 Γ— 124

Then I removed p-8:

<div class="bg-white w-96 h-auto rounded-lg shadow-lg border-2 border-black">
<h2 class="text-2xl font-bold text-center mb-6 text-gray-800">Welcome Back</h2>
</div>

Without p-8: Inspector shows 384 Γ— 60

How can 384 stay the same?! The width is 384px in both cases, but height changes dramatically. I'm guessing 384px is the width, right? But why doesn't it change?

The Answer That Unlocked Everything​

Frontend Mentor: Excellent observation! 🎯 You're thinking like a real frontend developer now!

Yes, you're absolutely correct! 384px is the width, and here's why it stays constant:

Why Width Stays at 384px​

w-96 = 96 Γ— 4px = 384px ← This is a FIXED width

No matter what you do inside (add padding, content, etc.), the total width remains 384px.

Why Height Changes (60px β†’ 124px)​

h-auto = height adapts to content ← This is FLEXIBLE

The height automatically adjusts based on:

  • Content inside (text, images, etc.)
  • Padding (top and bottom)
  • Margins of child elements

Breaking Down the Math​

Me: Can you show me exactly how we get from 60px to 124px?

Frontend Mentor: Absolutely! Let me break down both scenarios:

Without p-8 (384 Γ— 60)​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ No padding (0px) β”‚
β”‚ β”‚
β”‚ Welcome Back (text + margin) β”‚ ← ~60px
β”‚ β”‚
β”‚ No padding (0px) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Total height: ~60px

Calculation:

  • Top padding: 0px
  • Content (text + mb-6): ~60px
  • Bottom padding: 0px
  • Total: 60px βœ“

With p-8 (384 Γ— 124)​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Top padding (32px) β”‚ ← p-8 = padding: 32px
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ Welcome Back (text + margin) β”‚ ← ~60px
β”‚ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Bottom padding (32px) β”‚ ← p-8 = padding: 32px
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Total height: 124px

Calculation:

  • Top padding: 32px (p-8)
  • Content (text + mb-6): ~60px
  • Bottom padding: 32px (p-8)
  • Total: 32 + 60 + 32 = 124px βœ“

The CSS Box Model Explained​

Me: Okay, but why does width work differently? Why doesn't padding affect the width?

Frontend Mentor: Great question! This is where the CSS Box Model comes in. Let me show you:

The Traditional Box Model (content-box)​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Margin (outside, transparent) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Border (outline) β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ Padding (inside spacing) β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ Content β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ (your text/images) β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Traditional calculation:

Total width = width + padding-left + padding-right + border-left + border-right
Total height = height + padding-top + padding-bottom + border-top + border-bottom

Tailwind's Box Model (border-box) βœ¨β€‹

But Tailwind uses box-sizing: border-box by default!

box-sizing: border-box

This means: Width and height INCLUDE padding and border!

Modern calculation:

Total width = width (already includes padding and border)
Total height = height (already includes padding and border)

Visualizing Your Specific Example​

Me: So in my case with w-96 p-8, what's actually happening?

Frontend Mentor: Let me show you the breakdown:

Width Breakdown (384px total)​

Without p-8:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚ ← border-left: 2px
β”‚ Content: 380px β”‚ ← actual content space
β”‚ β”‚ ← border-right: 2px
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Total: 384px (w-96)

Calculation:

  • Border-left: 2px
  • Content area: 380px
  • Border-right: 2px
  • Total: 384px βœ“

With p-8:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚ β”‚ β”‚ ← border: 2px each side
β”‚ │←paddingβ†’ β”‚ β”‚ ← padding: 32px each side
β”‚ β”‚ Content: 316px β”‚ β”‚ ← remaining content space
β”‚ β”‚ β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Total: STILL 384px!

Calculation:

  • Border-left: 2px
  • Padding-left: 32px
  • Content area: 316px (384 - 4 border - 64 padding)
  • Padding-right: 32px
  • Border-right: 2px
  • Total: 2 + 32 + 316 + 32 + 2 = 384px βœ“

The key insight: Adding padding shrinks the content area but keeps total width at 384px!

Height Breakdown (Flexible)​

Without p-8:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Content: 60px β”‚ ← h-auto adjusts to content
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Total: 60px

With p-8:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Padding-top: 32px β”‚
β”‚ Content: 60px β”‚ ← h-auto adjusts to everything
β”‚ Padding-bottom: 32px β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Total: 124px

The key insight: h-auto means "calculate height based on everything inside (content + padding)!"

Fixed vs Auto Dimensions​

Me: So w-96 is fixed but h-auto is flexible?

Frontend Mentor: Exactly! Let me show you the difference:

Fixed Dimensions​

className="w-96 h-64"

Behavior:

  • Width: Always 384px (96 Γ— 4)
  • Height: Always 256px (64 Γ— 4)
  • Content overflows if it doesn't fit
  • Padding shrinks content area

Use when: You need exact, predictable sizes

Auto Dimensions​

className="w-auto h-auto"

Behavior:

  • Width: Adapts to content (or 100% of parent for block elements)
  • Height: Adapts to content
  • Never overflows (grows to fit)
  • Padding adds to total size

Use when: Content size varies or is unknown

Mixed (Your Case!)​

className="w-96 h-auto"

Behavior:

  • Width: Fixed at 384px ← Predictable horizontal size
  • Height: Flexible ← Adapts to content vertically
  • Perfect for cards, forms, modals

Use when: You want a fixed-width container that grows vertically

Real-World Examples​

Me: Can you show me some practical examples?

Frontend Mentor: Sure! Here are common patterns:

Example 1: Fixed-Width Card (Your Use Case)​

<div className="w-96 h-auto p-8 bg-white rounded-lg shadow-lg">
<h2 className="text-2xl font-bold mb-4">Title</h2>
<p>This card is always 384px wide, but height grows with content.</p>
<button className="mt-4 px-4 py-2 bg-blue-500 text-white rounded">
Click Me
</button>
</div>

Result:

  • Width: Always 384px
  • Height: Grows based on content
  • Padding included in width (content area is 348px: 384 - 32 - 32 - 2 - 2)

Example 2: Full-Width Container​

<div className="w-full h-auto p-8 bg-gray-100">
<p>This takes 100% width of parent, height grows with content.</p>
</div>

Result:

  • Width: 100% of parent (responsive!)
  • Height: Grows based on content
  • Padding included in width

Example 3: Fixed Box​

<div className="w-96 h-96 p-8 bg-white rounded-lg overflow-auto">
<p>This is a perfect 384Γ—384px square.</p>
<p>If content is too much, it scrolls!</p>
</div>

Result:

  • Width: Always 384px
  • Height: Always 384px
  • Content scrolls if it overflows (overflow-auto)

Common Mistakes to Avoid​

Me: What mistakes should I watch out for?

Frontend Mentor: Great question! Here are the most common pitfalls:

Mistake 1: Forgetting Border is Included​

❌ Thinking:
w-96 = 384px of content space

βœ… Reality:
w-96 = 384px TOTAL (includes padding and border)

Example:
className="w-96 p-8 border-2"
Content space = 384 - 32 - 32 - 2 - 2 = 316px

Mistake 2: Using Fixed Height with Variable Content​

❌ Bad:
<div className="w-96 h-64 p-8">
<p>{userGeneratedContent}</p> {/* Might overflow! */}
</div>

βœ… Good:
<div className="w-96 h-auto p-8">
<p>{userGeneratedContent}</p> {/* Always fits */}
</div>

Mistake 3: Not Accounting for Padding​

❌ Thinking:
"I want 400px content area, so I'll use w-[400px]"
<div className="w-[400px] p-8 border-2">
{/* Content space is only 332px! */}
</div>

βœ… Better:
"I want 400px content area, so I need 468px total"
<div className="w-[468px] p-8 border-2">
{/* Content space = 468 - 64 - 4 = 400px βœ“ */}
</div>

Debugging with Firefox Inspector​

Me: How can I use the Inspector to understand this better?

Frontend Mentor: Great question! Here's how to read the box model in Firefox:

Reading the Box Model Diagram​

When you inspect an element, Firefox shows:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ margin: 0 β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ border: 2 β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ padding: 32 β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ content: β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ 316 Γ— 60 β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Total: 384 Γ— 124

What to Look For​

Dimensions at the top:

  • 384 Γ— 124 ← Total element size (what you see)

Box model breakdown:

  • Content: 316 Γ— 60 ← Actual content area
  • Padding: 32 (all sides) ← Space inside border
  • Border: 2 (all sides) ← Border thickness
  • Margin: 0 ← Space outside border

Quick calculation check:

Width: 316 (content) + 32 + 32 (padding) + 2 + 2 (border) = 384 βœ“
Height: 60 (content) + 32 + 32 (padding) + 2 + 2 (border) = 128 β‰ˆ 124 βœ“

The Big Picture: When to Use What​

Me: So when should I use fixed width vs auto?

Frontend Mentor: Here's a decision guide:

Use Fixed Width (w-96, w-64, etc.)​

βœ… Good for:

  • Cards and modals
  • Form inputs
  • Buttons
  • Sidebar navigation
  • Fixed-layout designs

Example:

<div className="w-96 h-auto p-6 bg-white rounded-lg shadow-lg">
<h2 className="text-xl font-bold mb-4">Product Card</h2>
<img src="product.jpg" className="w-full h-48 object-cover" />
<p className="mt-4">Description text here...</p>
</div>

Use Auto Width (w-auto)​

βœ… Good for:

  • Inline buttons
  • Badge labels
  • Dropdown menus
  • Tooltips
  • Dynamic content

Example:

<button className="w-auto px-4 py-2 bg-blue-500 text-white rounded">
{buttonText} {/* Width adapts to text length */}
</button>

Use Full Width (w-full)​

βœ… Good for:

  • Form inputs
  • Mobile layouts
  • Responsive containers
  • Hero sections
  • Navigation bars

Example:

<input
type="email"
className="w-full h-auto p-2 border rounded"
placeholder="Enter your email"
/>

Key Takeaways​

Me: Let me make sure I understand this correctly:

Frontend Mentor: Perfect! Here's the summary:

Width Stays Constant Because:​

  1. w-96 is a fixed value: 384px always
  2. box-sizing: border-box: Width includes padding and border
  3. Adding padding shrinks content area: Total stays 384px
  4. Example:
    • No padding: Content = 380px (384 - 4 border)
    • With p-8: Content = 316px (384 - 64 padding - 4 border)

Height Changes Because:​

  1. h-auto is flexible: Adapts to content
  2. Content + padding determines height: Everything adds up
  3. Example:
    • No padding: Height = 60px (content only)
    • With p-8: Height = 124px (60 content + 64 padding)

The Box Model:​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ margin (outside, transparent) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ border (outline) β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ padding (inside space) β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ content (your text) β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

With box-sizing: border-box:
Total size = width/height (includes padding + border)

Best Practices:​

  1. Use w-fixed h-auto for cards, modals, forms
  2. Use w-full h-auto for responsive layouts
  3. Use w-auto h-auto for inline elements (buttons, badges)
  4. Always check Firefox Inspector to understand actual dimensions
  5. Remember: w-96 = 384px total (not content space!)

Me: This finally makes sense! The box model isn't randomβ€”it's a predictable system.

Frontend Mentor: Exactly! Once you understand how box-sizing: border-box works and the difference between fixed and auto dimensions, everything clicks. The Firefox Inspector becomes your best friend for debugging layout issues! πŸ”

Now you can confidently predict how dimensions will behave when you add padding, borders, or change content! 🎯


Have you had similar confusion with CSS dimensions? Share your "aha moment" in the comments! πŸ’¬