O rodapé pegajoso de Ryan Fait é muito bom, mas acho que sua estrutura básica está ausente *.
Versão Flexbox
Se você tiver a sorte de poder usar o flexbox sem precisar oferecer suporte a navegadores mais antigos, os rodapés fixos se tornam trivialmente fáceis e oferecem suporte a um rodapé de tamanho dinâmico.
O truque para fazer com que os rodapés fiquem fixos na parte inferior com o flexbox é ter outros elementos no mesmo contêiner flexíveis verticalmente. Tudo o que é necessário é um elemento wrapper de altura total com display: flex
e pelo menos um irmão com um flex
valor maior que 0
:
CSS:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#main-wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
}
article {
flex: 1;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#main-wrapper {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
min-height: 100%;
}
article {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
header {
background-color: #F00;
}
nav {
background-color: #FF0;
}
article {
background-color: #0F0;
}
footer {
background-color: #00F;
}
<div id="main-wrapper">
<header>
here be header
</header>
<nav>
</nav>
<article>
here be content
</article>
<footer>
here be footer
</footer>
</div>
Se você não pode usar o flexbox, minha estrutura base de escolha é:
<div class="page">
<div class="page__inner">
<header class="header">
<div class="header__inner">
</div>
</header>
<nav class="nav">
<div class="nav__inner">
</div>
</nav>
<main class="wrapper">
<div class="wrapper__inner">
<div class="content">
<div class="content__inner">
</div>
</div>
<div class="sidebar">
<div class="sidebar__inner">
</div>
</div>
</div>
</main>
<footer class="footer">
<div class="footer__inner">
</div>
</footer>
</div>
</div>
O que não está tão longe de:
<div id="main-wrapper">
<header>
</header>
<nav>
</nav>
<article>
</article>
<footer>
</footer>
</div>
O truque para fazer o rodapé aderir é ter o rodapé ancorado no preenchimento inferior do elemento que o contém. Isso requer que a altura do rodapé seja estática, mas descobri que os rodapés normalmente têm uma altura estática.
HTML:
<div id="main-wrapper">
...
<footer>
</footer>
</div>
CSS:
#main-wrapper {
padding: 0 0 100px;
position: relative;
}
footer {
bottom: 0;
height: 100px;
left: 0;
position: absolute;
width: 100%;
}
#main-wrapper {
padding: 0 0 100px;
position: relative;
}
footer {
bottom: 0;
height: 100px;
left: 0;
position: absolute;
width: 100%;
}
header {
background-color: #F00;
}
nav {
background-color: #FF0;
}
article {
background-color: #0F0;
}
footer {
background-color: #00F;
}
<div id="main-wrapper">
<header>
here be header
</header>
<nav>
</nav>
<article>
here be content
</article>
<footer>
here be footer
</footer>
</div>
Com o rodapé ancorado em #main-wrapper
, agora você precisa #main-wrapper
ter pelo menos a altura da página, a menos que seus filhos sejam mais longos. Isso é feito criando #main-wrapper
um min-height
de 100%
. Você também deve lembrar que seus pais, html
e body
precisam ser tão altos quanto a página também.
CSS:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#main-wrapper {
min-height: 100%;
padding: 0 0 100px;
position: relative;
}
footer {
bottom: 0;
height: 100px;
left: 0;
position: absolute;
width: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#main-wrapper {
min-height: 100%;
padding: 0 0 100px;
position: relative;
}
footer {
bottom: 0;
height: 100px;
left: 0;
position: absolute;
width: 100%;
}
header {
background-color: #F00;
}
nav {
background-color: #FF0;
}
article {
background-color: #0F0;
}
footer {
background-color: #00F;
}
<div id="main-wrapper">
<header>
here be header
</header>
<nav>
</nav>
<article>
here be content
</article>
<footer>
here be footer
</footer>
</div>
Claro, você deve estar questionando meu julgamento, já que este código está fazendo com que o rodapé caia da parte inferior da página, mesmo quando não há conteúdo. O último truque é mudar o modelo de caixa utilizado pelo #main-wrapper
modo que o min-height
de 100%
inclui o 100px
preenchimento.
CSS:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#main-wrapper {
box-sizing: border-box;
min-height: 100%;
padding: 0 0 100px;
position: relative;
}
footer {
bottom: 0;
height: 100px;
left: 0;
position: absolute;
width: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#main-wrapper {
box-sizing: border-box;
min-height: 100%;
padding: 0 0 100px;
position: relative;
}
footer {
bottom: 0;
height: 100px;
left: 0;
position: absolute;
width: 100%;
}
header {
background-color: #F00;
}
nav {
background-color: #FF0;
}
article {
background-color: #0F0;
}
footer {
background-color: #00F;
}
<div id="main-wrapper">
<header>
here be header
</header>
<nav>
</nav>
<article>
here be content
</article>
<footer>
here be footer
</footer>
</div>
E aí está, um rodapé com sua estrutura HTML original. Apenas certifique-se de que o footer
's height
é igual a #main-wrapper
' s padding-bottom
, e você deve estar configurado.
* O motivo pelo qual encontro falhas na estrutura do Fait é porque ele define os elementos .footer
e .header
em diferentes níveis hierárquicos enquanto adiciona um .push
elemento desnecessário .