Question
I am building a web application where the main content area should fill the remaining height of the viewport.
The page has two main sections:
- a
headerarea containing a logo and account information - a
contentarea that should stretch from below the header to the bottom of the screen
The header can have an arbitrary height, so I cannot hard-code its size.
Right now I am using a table-based layout:
<table id="page">
<tr>
<td id="tdheader">
<div id="header">...</div>
</td>
</tr>
<tr>
<td id="tdcontent">
<div id="content">...</div>
</td>
</tr>
</table>
#page {
height: 100%;
width: 100%;
}
#tdcontent {
height: 100%;
}
#content {
overflow: auto; /* or overflow: hidden; */
}
This fills the full page height without requiring the whole page to scroll.
Also, elements inside the content area may use percentage heights. For example:
- an element with
height: 100%should fill the content area - two elements with
height: 50%should each take half of the content area
If the header takes 20% of the screen height, then a table with height: 50% inside #content should take 40% of the screen height.
Is there a way to achieve this same effect without using a table for layout?
Short Answer
By the end of this page, you will understand how to make a section fill the remaining viewport height below a header with unknown height. You will learn why percentage heights often fail, how modern CSS layout tools like Flexbox solve this cleanly, and how to structure nested elements so height: 100% and other percentage-based heights work reliably.
Concept
In CSS, making one element fill the remaining height is a layout problem. The browser needs to know two things:
- the total available height
- how much space other elements already use
Traditional table layouts could do this automatically, which is why they were often used in older web apps. But modern CSS provides better tools for this, especially Flexbox.
The key idea is:
- make the page take up the full viewport height
- let the header size itself naturally
- allow the content area to grow and fill whatever space is left
This is exactly what Flexbox is designed for.
A very common beginner issue is trying to solve this with height: 100% alone. That often does not work unless every parent element has a defined height. Percentage heights depend on the height of the parent, so if the parent's height is auto, the child's percentage height cannot be resolved the way you expect.
For layouts like:
- header
- main content fills the rest
- nested panels inside content use percentage heights
Flexbox is usually the best solution.
Why this matters in real programming:
- dashboard layouts often need a fixed or variable header with a scrollable body
- admin apps commonly need side panels or content regions that fill available space
- modals, editors, and split-view UIs often depend on parent-controlled height
- data tables and charts frequently need to stretch inside a container
So this is not just about one div; it is about understanding how height flows through a layout.
Mental Model
Think of the page like a vertical stack of boxes inside a bookshelf with a fixed height.
- The bookshelf is the viewport.
- The header is a box that takes however much room it needs.
- The content area is a flexible box that expands to fill all remaining shelf space.
Inside that flexible content box, you can then divide the space again:
- one child can take
100% - two children can take
50%each
But this only works if the parent box has a real, known height.
So the rule of thumb is:
percentage heights work only when the parent has a definite height.
Flexbox helps create that definite remaining height automatically.
Syntax and Examples
Basic Flexbox solution
<div class="page">
<header class="header">
Logo and account info
</header>
<main class="content">
Main content
</main>
</div>
html, body {
height: 100%;
margin: 0;
}
.page {
height: 100vh;
display: flex;
flex-direction: column;
}
.header {
padding: 16px;
background: #ddd;
}
.content {
flex: 1;
overflow: auto;
background: #f5f5f5;
}
What this does
- makes as tall as the viewport
Step by Step Execution
Consider this example:
<div class="page">
<header class="header">My Header</header>
<main class="content">
<div class="box">I fill the remaining height</div>
</main>
</div>
html, body {
height: 100%;
margin: 0;
}
.page {
height: 100vh;
display: flex;
flex-direction: column;
}
.header {
padding: 24px;
}
.content {
flex: 1;
}
.box {
height: 100%;
background: peachpuff;
}
Real World Use Cases
Where this pattern is used
Dashboards
A dashboard may have:
- a top navigation bar
- a chart or data table below it
The chart area should fill the remaining height and scroll internally if needed.
Admin panels
Many admin tools use:
- a header with account actions
- a main working area below
This keeps the top controls visible while the main content grows and scrolls.
Chat applications
A chat app often has:
- a header with room or user info
- a message list filling the remaining space
- sometimes nested panels inside the content area
Code editors and IDE-like layouts
Browser-based editors often need:
- a toolbar at the top
- editor panels filling the rest of the screen
Data tables
A page may need a filter bar on top and a table below that fills the rest of the viewport without making the entire page scroll.
Real Codebase Usage
In real projects, developers usually combine this pattern with a few common layout habits.
1. Flex column shell
A common app shell looks like this:
.app {
height: 100vh;
display: flex;
flex-direction: column;
}
.app-main {
flex: 1;
min-height: 0;
}
This creates a reliable full-height page structure.
2. Scroll only where needed
Instead of scrolling the whole page, developers often scroll just the content region:
.app-main {
flex: 1;
overflow: auto;
min-height: 0;
}
This is useful for sticky headers, fixed toolbars, and split layouts.
3. Nested flex layouts
Inside the content area, developers often create another flex layout:
.content {
display: flex;
flex-direction: column;
}
.panel {
flex: 1;
}
Common Mistakes
1. Using height: 100% without defining parent height
Broken example:
.content {
height: 100%;
}
This does not work if the parent does not have a definite height.
Fix
Make the parent a full-height container or use Flexbox:
.page {
height: 100vh;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
}
2. Forgetting to set html, body height
If you rely on percentage heights, this matters.
Broken example:
body {
margin: 0;
}
.page {
height: 100%;
}
Fix
html, body {
: ;
: ;
}
Comparisons
| Approach | Best for | Handles unknown header height | Supports remaining space well | Notes |
|---|---|---|---|---|
table layout | Old layouts | Yes | Yes | Works, but not recommended for page layout |
height: 100% only | Simple cases | No | Weak | Requires defined heights on all parents |
calc(100vh - 80px) | Fixed-height header | No | Good | Breaks if header height changes |
| Flexbox | Modern app layouts | Yes | Excellent | Best fit for header + remaining content |
Cheat Sheet
html, body {
height: 100%;
margin: 0;
}
.page {
height: 100vh;
display: flex;
flex-direction: column;
}
.header {
/* natural height */
}
.content {
flex: 1;
min-height: 0;
overflow: auto;
}
Rules to remember
height: 100%needs a parent with a defined height.flex: 1makes an element fill remaining space.- Use
min-height: 0on flex children that should shrink and scroll. - Use tables for tabular data, not page layout.
- Use
100vhwhen you want viewport height. - If child elements use percentage heights, the parent must have a real computed height.
Useful alternatives
Flexbox
.page {
display: flex;
flex-direction: column;
: ;
}
FAQ
How do I make a div take the rest of the page height?
Use a parent container with display: flex, flex-direction: column, and give the content area flex: 1.
Why does height: 100% not work in my div?
Because percentage height only works when the parent has a defined height. If the parent height is auto, the child cannot reliably fill it.
Can I do this without knowing the header height?
Yes. Flexbox and Grid both work well when the header has dynamic height.
Is using a table for page layout bad?
It is outdated for general layout. Tables are intended for tabular data, not app page structure.
What if I want only the content area to scroll?
Set overflow: auto on the content area and keep the overall page container at viewport height.
Can children inside the content area use height: 50% or height: 100%?
Yes, as long as the content area has a definite height, which Flexbox can provide.
Should I use Flexbox or Grid for this layout?
Use Flexbox for a simple vertical header/content layout. Use Grid if the page also needs more complex rows and columns.
Mini Project
Description
Build a simple app-style page with a variable-height header and a content area that fills the rest of the screen. Inside the content area, split the space into two equal sections using percentage heights. This demonstrates how to create a full-height layout without table-based markup.
Goal
Create a responsive page where the header keeps its natural height and the content area fills the remaining viewport height.
Requirements
- Create a page container that fills the viewport height.
- Add a header with natural, content-based height.
- Make the main content area fill the remaining vertical space.
- Inside the content area, add two panels that each take 50% of the content height.
- Make the content area scroll if its content becomes too large.
Keep learning
Related questions
Can You Style Half a Character in CSS? Text Effects with CSS and JavaScript
Learn how to style half of a character using CSS and JavaScript, including overlay techniques for dynamic text effects.
Get Screen, Page, and Browser Window Size in JavaScript
Learn how to get screen size, viewport size, page size, and scroll position in JavaScript across major browsers.
Get the Selected Radio Button Value with jQuery
Learn how to find which radio button is selected in jQuery and get its value with simple examples and common mistakes.