The Cover Layout
The Cover layout — another pattern from Every Layout — is the classic full-viewport hero section: a header at the top, a footer at the bottom (or neither), and a centered block of content that takes up whatever space is left, growing or shrinking with the viewport instead of scrolling awkwardly. It is the pattern behind almost every landing-page hero.
The core recipe
Flexbox in column direction, with the centered content pushed to fill remaining space using flex: 1 and its own auto-margins for centering.
.cover {
display: flex;
flex-direction: column;
min-height: 100dvh; /* fills the real visible viewport height */
padding: 1.5rem;
}
.cover > * {
margin-block: 1rem; /* default rhythm between direct children */
}
.cover > .cover-centered {
margin-block: auto; /* pushes itself to vertical center of remaining space */
text-align: center;
}
/* Header/footer opt out of centering, stay pinned to their edge */
.cover > header,
.cover > footer {
margin-block: 0;
}align-items: center directly on .cover, the header and footer also get pulled to the middle. Using auto margins on just the centered child lets it consume the leftover space and center itself, while header and footer stay naturally pinned to the top and bottom.Full hero section example
<div class="cover">
<header class="cover-header">
<img src="/logo.svg" alt="Company logo" />
</header>
<div class="cover-centered">
<h1>Build faster, ship sooner</h1>
<p>Everything your team needs, in one place.</p>
<a class="cta" href="/signup">Get started</a>
</div>
<footer class="cover-footer">
<p>Scroll to learn more ↓</p>
</footer>
</div>.cover {
display: flex;
flex-direction: column;
min-height: 100dvh;
padding: 2rem;
background: linear-gradient(160deg, #1e293b, #0f172a);
color: white;
}
.cover-header {
display: flex;
justify-content: center;
}
.cover-centered {
margin-block: auto;
text-align: center;
max-width: 40ch;
margin-inline: auto;
}
.cover-centered h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
margin-bottom: 0.5rem;
}
.cta {
display: inline-block;
margin-top: 1.5rem;
padding: 0.75rem 1.5rem;
border-radius: 8px;
background: white;
color: #0f172a;
font-weight: 600;
text-decoration: none;
}
.cover-footer {
text-align: center;
opacity: 0.7;
font-size: 0.875rem;
}Why min-height: 100dvh instead of 100vh
100vh is measured against the largest possible viewport, which includes space behind the collapsing address bar. That can push the footer off-screen on load.100dvh (dynamic viewport height) tracks the actually visible viewport, so the cover always fits the real screen..cover {
min-height: 100vh; /* fallback for browsers without dvh support */
min-height: 100dvh; /* preferred, overrides the line above where supported */
}Variation: cover without header/footer
Not every cover needs both edges — a simple "centered content, full height" section is just the same recipe with only one child.
.cover-simple {
display: flex;
flex-direction: column;
justify-content: center; /* fine here since there's nothing else to push away */
align-items: center;
min-height: 100dvh;
text-align: center;
}Use
margin-block: autoon the centered child when a header and/or footer must stay pinned to the edgesUse plain
justify-content: centeron the container when there is nothing else competing for spaceAlways use
100dvh(with a100vhfallback) for full-viewport height on anything mobile users will seeConstrain the centered content with a
max-widthinchunits so hero copy stays readable on ultra-wide screens
Variation: background image with an overlay
A common hero variant layers a dark scrim over a background photo so white text stays legible. The Cover recipe itself does not change — only the background layers do.
.cover--photo {
display: flex;
flex-direction: column;
min-height: 100dvh;
padding: 2rem;
color: white;
background-image:
linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
url('/hero-photo.jpg');
background-size: cover;
background-position: center;
}Stacking multiple cover sections
A landing page is often several Cover sections stacked vertically — a hero, then a feature highlight, then a call-to-action footer section — each independently full-height and independently centered.
.cover {
display: flex;
flex-direction: column;
min-height: 100dvh;
}
/* Each section reuses the same recipe, scroll-snapping between them
for a slide-deck feel if desired */
.sections {
scroll-snap-type: y mandatory;
}
.cover {
scroll-snap-align: start;
}Accessibility considerations
Add a visually-hidden skip link before the first cover section so keyboard users can bypass a tall hero and reach the main content directly
Ensure text over a background image/gradient still meets contrast requirements at every viewport size, not just the one used to design it
If cover sections scroll-snap, respect
prefers-reduced-motionand consider disabling forced snapping for users who opted out of motionDo not rely on scroll position alone to convey content order for screen readers — the underlying DOM order must already make sense read top to bottom
@media (prefers-reduced-motion: reduce) {
.sections {
scroll-snap-type: none; /* let users scroll freely without a
snapping motion effect */
}
}Sticky nav inside a cover section
When the header inside a cover section must remain visible while the rest of the page scrolls past, position: sticky on the header (rather than the whole section) keeps the Cover recipe's flex structure intact while pinning just that one child.
.cover-header {
position: sticky;
top: 0;
z-index: 10;
background: rgba(15, 23, 42, 0.9);
backdrop-filter: blur(8px);
}