Remaining space
To make <main>
take up the remaining space of <body>
, you can use:
CSS Grid
CSS Grid allows us to define a grid layout and distribute space. By declaring <header>
's row height to auto
, we can assign <main>
's row the remaining height with flexible lengths (fr
):
body {
height: 100vh;
display: grid;
grid-template-rows: auto 1fr;
}
/*Ignore; for demonstrational purposes*/
body {margin: 0}
header {
height: 2rem;
background-color: red;
}
main {
background-color: blue;
}
<body>
<header></header>
<main></main>
</body>
Flexbox
Flexbox allows us to lay out flex children along a main axis. We can let a child grow to fill that axis with the flex-grow
property:
body {
height: 100vh;
display: flex;
flex-direction: column;
}
main {flex-grow: 1}
/*Ignore; for demonstrational purposes*/
body {margin: 0}
header {
height: 2rem;
background-color: red;
}
main {background-color: blue}
<body>
<header></header>
<main></main>
</body>
Centering text
The large and prominent section "above the fold" is commonly called hero section, hero banner or similar.
When placing an out-of-flow header onto the hero section, then centering can be done by absolute positioning then translating.
Note: With above, make sure not to place any (hero) content behind the header!
Centering may become tricky if the hero section is not the same size as the viewport but you still want its content to be centered to the viewport.
When centering with CSS Grid and place-items: center
, then content is only centered to its parent but not to the viewport:
body {
height: 100vh;
display: grid;
grid-template-rows: auto 1fr;
}
header {height: 4rem}
#hero {
height: 100%;
display: grid;
place-items: center;
}
/*Ignore; for demonstrational purposes*/
body {margin: 0}
header {background-color: lightpink}
main {background-color: lightblue}
/*Center cross*/
body::before, body::after {
content: "";
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: black;
}
body::before {
width: 2rem;
height: 2px;
}
body::after {
width: 2px;
height: 2rem;
}
<body>
<header></header>
<main>
<section id=hero>
<span id=hero-content>Hero content</span>
</section>
</main>
</body>
But if we know the header's (static) height then we can take it into account:
body {
--header-height: 4rem;
height: 100vh;
display: grid;
grid-template-rows: auto 1fr;
}
header {height: var(--header-height)}
#hero {
height: 100%;
display: grid;
place-items: center;
}
#hero-content {
margin-top: calc(-1 * var(--header-height));
}
/*Ignore; for demonstrational purposes*/
body {margin: 0}
header {background-color: lightpink}
main {background-color: lightblue}
/*Center cross*/
body::before, body::after {
content: "";
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: black;
}
body::before {
width: 2rem;
height: 2px;
}
body::after {
width: 2px;
height: 2rem;
}
<body>
<header></header>
<main>
<section id=hero>
<span id=hero-content>Hero content</span>
</section>
</main>
</body>