Below are 4 different methods of mine:
In each example the texts are freely-editable to illustrate how the content would render in different scenarios.
1) Flexbox
body{ height:100vh; margin:0; }
header{ min-height:50px; background:lightcyan; }
footer{ min-height:50px; background:PapayaWhip; }
/* Trick */
body{
display:flex;
flex-direction:column;
}
footer{
margin-top:auto;
}
<body>
<header contentEditable>Header</header>
<article contentEditable>Content</article>
<footer contentEditable>Footer</footer>
</body>
2) Grid
body{
min-height: 100vh;
margin: 0;
display: grid;
grid-template-rows: auto 1fr auto;
}
header{
min-height:50px;
background:lightcyan;
}
footer{
min-height:50px;
background:PapayaWhip;
}
<body>
<header contentEditable>Header</header>
<article contentEditable>Content</article>
<footer contentEditable>Footer</footer>
</body>
This method below uses a “trick” by placing an ::after
pseudo-element on the body
, and set it to have the exact height of the footer, so it will occupy the exact same space the footer does, so when the footer is absolute
positioned over it, it would appear like the footer is really taking up space and eliminate the negative affects of it’s absolute positioning (for example, going over the body’s content)
3) position:absolute
(no dynamic footer height)
body{ min-height:100vh; margin:0; position:relative; }
header{ min-height:50px; background:lightcyan; }
footer{ background:PapayaWhip; }
/* Trick: */
body {
position: relative;
}
body::after {
content: '';
display: block;
height: 50px; /* Set same as footer's height */
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 50px;
}
<body>
<header contentEditable>Header</header>
<article contentEditable>Content</article>
<footer contentEditable>Footer</footer>
</body>
4) Table-layout
html{ height:100%; }
body { min-height:100%; margin:0; }
header {
height: 50px;
background: lightcyan;
}
article {
height: 1%;
}
footer {
height: 50px;
background: PapayaWhip;
}
/**** Trick: ****/
body {
display: table;
width: 100%;
}
body > footer {
display: table-row;
}
<body>
<header contentEditable>Header</header>
<article contentEditable>Content</article>
<footer contentEditable>Footer</footer>
</body>