Pie de página en la parte inferior de la página o contenido, el que sea inferior

92

Tengo la siguiente estructura:

<body>
    <div id="main-wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <footer>
        </footer>
    </div>
</body>

Carga contenido dinámicamente en el <article>uso de javascript. Debido a esto, la altura del <article>bloque puede cambiar.

Quiero que el <footer>bloque esté en la parte inferior de la página cuando haya mucho contenido, o en la parte inferior de la ventana del navegador cuando solo existan unas pocas líneas de contenido.

De momento puedo hacer una u otra ... pero no ambas.

Entonces, ¿alguien sabe cómo puedo hacer esto? Consiga <footer>que se pegue en la parte inferior de la página / contenido o en la parte inferior de la pantalla, dependiendo de cuál sea la más baja.

Será
fuente
¿Le importaría a la gente comentar por qué rechazaron una pregunta de 2 años?
Será el
Vamos, han pasado casi 6 años ...
Will

Respuestas:

99

El pie de página pegajoso de Ryan Fait es muy agradable, sin embargo, encuentro que falta su estructura básica *.


Versión Flexbox

Si tiene la suerte de poder usar flexbox sin necesidad de admitir navegadores antiguos, los pies de página adhesivos se vuelven trivialmente fáciles y admiten un pie de página de tamaño dinámico.

El truco para hacer que los pies de página se peguen al fondo con flexbox es hacer que otros elementos en el mismo contenedor se flexionen verticalmente. Todo lo que se necesita es un elemento contenedor de altura completa con display: flexal menos un hermano con un flexvalor mayor que 0:

CSS:
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#main-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

article {
  flex: 1;
}


Si no puede usar flexbox, mi estructura base de elección es:

<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>

Que no está tan lejos de:

<div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
</div>

El truco para hacer que el pie de página se adhiera es tener el pie de página anclado al relleno inferior de su elemento contenedor. Esto requiere que la altura del pie de página sea estática, pero he descubierto que los pies de página suelen tener una 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%;
}

Con el pie de página anclado a #main-wrapper, ahora debe #main-wrappertener al menos la altura de la página, a menos que sus hijos sean más largos. Esto se hace haciendo que #main-wrappertenga una min-heightde 100%. También debe recordar que sus padres, htmly bodydebe ser tan alto como la página.

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%;
}

Por supuesto, debería cuestionar mi juicio, ya que este código está obligando a que el pie de página se caiga de la parte inferior de la página, incluso cuando no hay contenido. El último truco es cambiar el modelo de caja que utiliza el #main-wrappermodo que el min-heightdel 100%incluye el 100pxrelleno.

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%;
}

Y ahí lo tienes, un pie de página adhesivo con tu estructura HTML original. Solo asegúrese de que footer's heightsea ​​igual a #main-wrapper' s padding-bottom, y debería estar configurado.


* La razón por la que encuentro fallas en la estructura de Fait es porque establece los elementos .footery .headeren diferentes niveles jerárquicos mientras agrega un .pushelemento innecesario .

zzzzBov
fuente
Necesitaba agregar #main-wrapper *:first-child { margin-top: 0; }, de lo contrario, la página sería demasiado larga en el margen superior del primer niño (lo que provocaría una barra de desplazamiento innecesaria en páginas cortas).
Florian Brucker
Gracias, @zzzzBov por esta explicación detallada, y especialmente por mencionar la dirección flexible (ojalá hubiera encontrado esto antes, ¡me hubiera ahorrado un par de horas! :)
ea0723
La versión Flexbox no me funciona en IE11, ¡pero el otro enfoque está bien para mí! ¡Gracias y +1!
Matt
@Matt, debe usar prefijos del navegador para que flexbox funcione en IE11. use una herramienta como autoprefixer y nunca tendrá que preocuparse por agregarlos manualmente.
zzzzBov
2
El enlace de pie de página pegajoso parece estar roto debido a que su sitio se convirtió en un aviso de In Memoriam para él. Además, no hay versiones en caché debido a la configuración de robots.txt
tzrlk
13

El pie de página pegajoso de Ryan Fait es una solución simple que he usado varias veces en el pasado.

HTML básico :

<div class="wrapper">
    <div class="header">
        <h1>CSS Sticky Footer</h1>
    </div>
    <div class="content"></div>
    <div class="push"></div>
</div>
<div class="footer"></div>

CSS :

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

/*

Sticky Footer by Ryan Fait
http://ryanfait.com/

*/

Traducir esto para que sea similar a lo que ya tiene resultados con algo como esto:

HTML :

<body>
    <div class="wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <div class="push"></div>
    </div>
    <footer>
    </footer>
</body>

CSS:

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

Simplemente no olvide actualizar el negativo en el margen del contenedor para que coincida con la altura de su pie de página y presione div. ¡Buena suerte!

Josh Mein
fuente
4
Me encanta la forma en que puso el comentario al final, apropiado para una solución de pie de página: D
Madara's Ghost
No es necesario cambiar el marcado para este estilo en particular.
zzzzBov
@zzzzBov No tengo mucho tiempo para investigar más a fondo en este momento, pero ¿a qué te refieres exactamente?
Josh Mein
Estoy en mi cajero automático móvil, así que no puedo escribir una respuesta completa, de lo contrario ya lo habría hecho. El comentario fue más, así que recordaría agregar una respuesta más tarde.
zzzzBov
@JoshMein, agregué una respuesta que explica cómo hacer que el pie de página se mantenga sin alterar la estructura provista.
zzzzBov
0

Estaba buscando resolver este problema sin agregar ningún marcado adicional, así que terminé usando la siguiente solución:

article {
  min-height: calc(100vh - 150px); /* deduct the height or margins of any other elements within wrapping container*/
}

footer {
  height: 50px;
}

header {
   height: 50px;
}

nav {
  height: 50px;
}
<body>
  <div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
  </div>
</body>

Debe conocer las alturas de encabezado, navegación y pie de página para poder establecer la altura mínima del artículo. Por esto, si el artículo tiene solo unas pocas líneas de contenido, el pie de página se pegará en la parte inferior de la ventana del navegador, de lo contrario, irá debajo de todo el contenido.

Puede encontrar esta y otras soluciones publicadas arriba aquí: https://css-tricks.com/couple-takes-sticky-footer/

Galina E
fuente