Question

CSS 100% Height with Padding and Margins: box-sizing Explained

Question

With HTML and CSS, how can an element fill 100% of its parent’s width and/or height while still having padding or margins without causing overflow?

For example, if a parent is 200px tall and a child has height: 100% plus 5px of padding on every side, I want the child’s total outer height to remain 200px. Its content area should shrink to leave room for the padding.

The usual CSS appears to overflow:

#myDiv {
  width: 100%;
  height: 100%;
  padding: 5px;
}

How can this be done reliably when the parent has an arbitrary size? For example, how can the following black element have 25px of padding without making the page tall enough to display scrollbars?

<html style="height: 100%;">
  <body style="height: 100%;">
    <div style="background-color: black; height: 100%; padding: 25px;"></div>
  </body>
</html>

Short Answer

You will learn how the CSS box model calculates percentage dimensions, why height: 100% plus padding can overflow, and how box-sizing: border-box keeps padding and borders inside an element’s declared size. You will also see when margins require a different layout approach, such as Flexbox.

Concept

By default, CSS uses the content-box sizing model.

With content-box, a declared width or height applies only to the content area. Padding and borders are added outside that size.

.panel {
  height: 100%;
  padding: 25px;
}

If the parent is 200px tall:

  • Content height: 200px (100% of the parent)
  • Top and bottom padding: 25px + 25px
  • Total height: 250px

That extra 50px can create overflow and scrollbars.

Use box-sizing: border-box when the declared size should represent the element’s full border box. Padding and borders are then included inside the specified width or height.

.panel {
  height: 100%;
  padding: 25px;
  box-sizing: border-box;
}

Now, in a 200px-tall parent, the panel remains 200px tall. Its content area becomes 150px tall after accounting for the vertical padding.

This matters because layouts commonly need elements to fill cards, panels, dialogs, sidebars, or the viewport without unexpectedly exceeding their containers.

Mental Model

Think of a declared height as a box you are given to pack.

  • With content-box, height: 200px gives you a 200px content package, then padding is wrapped around the outside. The final parcel gets larger.
  • With border-box, height: 200px is the final parcel size. Padding must fit inside it, so the usable content space becomes smaller.

Margins are different: they are space outside the parcel. box-sizing cannot pull margins inside a 100% size. If you need outside gaps while filling a parent, let a layout system such as Flexbox calculate the remaining space.

Take Quiz

Syntax and Examples

The key declaration is:

box-sizing: border-box;

Apply it to one element:

<div class="parent">
  <div class="child">Content goes here</div>
</div>
.parent {
  height: 200px;
  background: #dbeafe;
}

.child {
  height: 100%;
  padding: 25px;
  border: 5px solid #1d4ed8;
  box-sizing: border-box;
  background: #93c5fd;
}

The child’s complete visible box, including its padding and 5px border, is 200px high. Its content area is reduced automatically.

A common project-wide reset is:

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

This makes width and height easier to reason about for normal elements and pseudo-elements.

For a full-page panel, give percentage heights a definite reference height and remove the browser’s default body margin:

html,
body {
  height: 100%;
  margin: 0;
}

.page-panel {
  height: 100%;
  padding: 25px;
  box-sizing: border-box;
  background: black;
  color: white;
}

Step by Step Execution

Consider this markup:

<div class="parent">
  <div class="child">Hello</div>
</div>
.parent {
  height: 200px;
}

.child {
  height: 100%;
  padding: 20px;
  border: 5px solid black;
  box-sizing: border-box;
}

What happens:

  1. .parent has a definite height of 200px.
  2. .child resolves height: 100% to 200px.
  3. Because it uses border-box, that 200px includes content, padding, and border.
  4. The child has 20px top padding and 20px bottom padding: 40px total.
  5. The child has 5px top border and 5px bottom border: 10px total.
  6. The content height is 200 - 40 - 10, which is 150px.
  7. The child’s outer size remains exactly 200px, so it does not overflow solely because of its padding and border.

Without box-sizing: border-box, the content would be 200px high and the total visible height would become 250px.

Real World Use Cases

border-box is useful whenever an element must fit predictably inside a known area:

  • Dashboard panels: A panel fills a grid cell while retaining internal spacing.
  • Modal dialogs: A dialog with width: 100% inside a constrained container does not overflow because of its padding.
  • Form controls: Inputs and textareas retain their expected width even when padding and borders are applied.
  • Full-height application layouts: A sidebar or content region fills the available height without gaining extra pixels from padding.
  • Reusable components: Cards can accept arbitrary padding without callers having to recalculate their width or height.

For external spacing between sibling elements, use layout gaps where possible:

.toolbar {
  display: flex;
  gap: 12px;
}

gap creates space between items without making an individual width: 100% item exceed its container.

Take Quiz

Real Codebase Usage

Most modern codebases set border-box globally near the start of their stylesheet:

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

This prevents many width and height surprises in components.

For a full-height application shell, developers often use viewport-relative sizing and Flexbox rather than nesting many percentage heights:

.app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.app__main {
  flex: 1;
  padding: 24px;
  box-sizing: border-box;
}

For a child that needs external margins but must still fit in a parent, use a flex container and let the child grow into the remaining space:

.parent {
  height: 300px;
  display: flex;
  flex-direction: column;
}

.child {
  flex: 1;
  margin: 16px;
}

Here, Flexbox accounts for the child’s margins while distributing available space. This is more reliable than combining height: 100% with vertical margins.

Common Mistakes

Expecting content-box to include padding

This overflows because the 100% height is the content height:

.child {
  height: 100%;
  padding: 25px;
}

Fix it with:

.child {
  height: 100%;
  padding: 25px;
  box-sizing: border-box;
}

Forgetting that percentage height needs a definite parent height

.parent {
  height: auto;
}

.child {
  height: 100%;
}

A percentage height is often not useful when the parent’s height is determined by its content. Set a definite parent height, use min-height: 100vh, or use Flexbox/Grid depending on the layout.

Assuming box-sizing includes margins

.child {
  height: 100%;
  margin: 20px 0;
  box-sizing: border-box;
}

The margins remain outside the box, so this still needs more than the parent’s height. Use Flexbox, Grid, a wrapper, or a calculated value only when appropriate.

Forgetting the default body margin

Browsers usually apply a default margin to body. A full-page element can appear to have unwanted outer space or cause overflow. Reset it when building edge-to-edge layouts:

html,
body {
  margin: 0;
  height: 100%;
}

Using overflow: hidden as the first fix

overflow: hidden can hide the symptom while clipping important content. First ensure the box dimensions are correct; use overflow rules only when clipping or scrolling is truly intended.

Comparisons

ApproachDoes declared width/height include padding and border?Does it include margin?Best use
Default content-boxNoNoCases where content dimensions must be exact
box-sizing: border-boxYesNoMost component and page layout sizing
calc(100% - 50px)Can account for known space manuallyNoLimited, fixed calculations
Flexbox with flex: 1Layout calculates remaining spaceMargins participate in layoutFilling available space among siblings
CSS Grid with 1frGrid distributes available spaceGaps are handled by gridTwo-dimensional layouts

calc() can solve a fixed-padding case:

.child {
  height: calc(100% - 50px);
  padding: 25px;
}

However, border-box is clearer and automatically includes both padding and border. Prefer it when the goal is simply “this element’s outside size should be 100%.”

Take Quiz

Cheat Sheet

/* Recommended global sizing rule */
*,
*::before,
*::after {
  box-sizing: border-box;
}
/* Fill a parent without padding/border overflow */
.child {
  width: 100%;
  height: 100%;
  padding: 16px;
  border: 1px solid #000;
  box-sizing: border-box;
}
  • Default box-sizing is content-box.
  • content-box: declared size is the content area only.
  • border-box: declared size includes content, padding, and border.
  • Margins are always outside the box and are not included by border-box.
  • height: 100% needs a parent with a resolvable, definite height.
  • For edge-to-edge pages, commonly set html, body { height: 100%; margin: 0; }.
  • Use Flexbox or Grid when an item must fill remaining space while retaining outer gaps.

FAQ

Why does height: 100% overflow when I add padding?

The default content-box model treats 100% as the content height. Padding and borders are then added outside it, increasing the total height.

How do I make padding count inside width: 100% or height: 100%?

Add box-sizing: border-box. The specified width or height will include padding and borders.

Does box-sizing: border-box include margins?

No. Margins are external space outside the border box. Use Flexbox, Grid, a wrapper, or another layout strategy when margins must fit inside a container.

Why is height: 100% not working for my child element?

Usually, its parent does not have a definite height. Give the parent a fixed height, a viewport-relative height such as 100vh, or use a layout system that distributes height.

Should I use border-box globally?

Usually, yes. The global *, *::before, and *::after rule gives components more predictable sizing.

Do I need height: 100% for a full-screen element?

You can use it when html and body also have defined heights. For many app layouts, min-height: 100vh is a straightforward alternative.

Is calc(100% - padding) better than border-box?

Usually not. border-box is simpler and automatically handles padding and border. Use calc() for calculations that cannot be expressed through normal box sizing.

Take Quiz

Mini Project

Description

Build a full-height application panel that fits the viewport, has comfortable internal padding, and does not create scrollbars merely because padding was added. This mirrors a common layout used for dashboards, settings pages, and editor interfaces.

Goal

Create a viewport-filling panel whose total height includes its padding and border.

Requirements

Create an HTML page with a panel containing a heading and paragraph. Make the panel fill the browser viewport vertically. Add 24px padding and a border to the panel. Ensure the panel does not overflow the viewport because of its padding or border. Remove default page margins.

Take Quiz

Keep learning

Related questions

View more