Modern Layout Pattern
A full-height layout with a sticky header and a footer that always stays at the bottom. Built with CSS Grid for maximum flexibility and modern browser support.
Layout Features
- Sticky Header: Remains visible while scrolling
- Flexible Content: Content area grows to fill available space
- Bottom Footer: Always positioned at the bottom (not fixed)
- Full Viewport Height: Uses 100vh for proper spacing
- CSS Grid: Modern approach with grid-template-rows
The Grid Approach
This layout uses CSS Grid with three rows: header (auto), content (1fr), and
footer (auto). The 1fr on the content area makes it expand to fill
all available space, pushing the footer to the bottom even when content is short.
.page-container {
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto;
}
.sticky-header {
position: sticky;
top: 0;
z-index: 100;
}
Why This Works
The min-height: 100vh ensures the container is at least the
height of the viewport. The 1fr unit in grid-template-rows
makes the main content area grow to fill remaining space, which pushes
the footer to the bottom when content is short.
Sticky vs Fixed Positioning
Sticky Position
Behaves like relative until scrolling reaches threshold, then acts like fixed. Returns to normal flow when scrolling back.
Fixed Position
Always removed from document flow. Stays in the same position regardless of scrolling. Can cause layout issues.
Best Practice
Use sticky for headers that should scroll naturally at first, then stick. Use fixed for elements that should always be visible.
Sticky Header Implementation
The header uses position: sticky with top: 0.
This means it scrolls normally until it reaches the top of the viewport,
then sticks there. The z-index: 100 ensures it stays above
other content.
.sticky-header {
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
Footer Placement
Unlike a fixed footer that's always visible, this footer stays at the bottom of the content. When content is short, it sits at the bottom of the viewport. When content is long, it appears after all the content, requiring scrolling to reach.
Grid Template Rows Breakdown
auto: Header takes only the space it needs
1fr: Content expands to fill available space
auto: Footer takes only the space it needs
Alternative Approaches
Before CSS Grid, developers used various techniques to achieve this layout:
Flexbox Method
Use flex-direction: column and flex: 1
on main content. Works well but requires more properties.
Negative Margin
Use min-height: 100vh and negative margins on footer.
Hacky and requires careful calculation.
Calc() Function
Calculate content height using calc(100vh - header - footer).
Brittle and hard to maintain.
Scroll Progress Indicator
This demo includes a scroll progress bar at the very top of the page. It's a nice enhancement that shows how far through the content the user has scrolled.
const scrollProgress = document.getElementById('scrollProgress');
window.addEventListener('scroll', () => {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight -
window.innerHeight;
const scrollPercent = (scrollTop / docHeight) * 100;
scrollProgress.style.width = scrollPercent + '%';
});
Browser Support
CSS Grid is supported in all modern browsers (Chrome 57+, Firefox 52+, Safari 10.1+, Edge 16+). Sticky positioning is also well-supported (Chrome 56+, Firefox 59+, Safari 13+, Edge 16+).
Fallback Strategy
For older browsers, you can use feature queries (@supports)
to provide a flexbox fallback. The layout will still work, just without
the sticky header behavior.
Use Cases
Single Page Apps
Perfect for SPAs where you want consistent navigation that's always accessible while maintaining a clean layout.
Documentation Sites
Ideal for docs where users need to scroll through long content but still access navigation quickly.
Admin Panels
Great for dashboards where you want the header always visible but don't want to waste vertical space.
Landing Pages
Works well for marketing pages with multiple sections and a comprehensive footer at the end.
Additional Content
This section exists to demonstrate the scrolling behavior. Notice how the header remains visible as you scroll down the page. The scroll progress bar at the top also updates as you move through the content.
Try scrolling all the way to the bottom to see how the footer sits naturally at the end of the content. Then scroll back up to see the sticky header in action. This is much more elegant than a fixed header that always takes up space at the top of the viewport.