Cómo alinear el contenido de un div al fondo


1164

Digamos que tengo el siguiente código CSS y HTML:

#header {
  height: 150px;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines)
</div>

La sección del encabezado tiene una altura fija, pero el contenido del encabezado puede cambiar.

Me gustaría que el contenido del encabezado se alinee verticalmente con la parte inferior de la sección del encabezado, de modo que la última línea de texto se "pegue" en la parte inferior de la sección del encabezado.

Entonces, si solo hay una línea de texto, sería como:

-----------------------------
El | Título del encabezado
El |
El |
El |
El | contenido del encabezado (que resulta en una línea)
-----------------------------

Y si hubiera tres líneas:

-----------------------------
El | Título del encabezado
El |
El | contenido del encabezado (que es tan
El | muchas cosas que perfectamente
El | abarca más de tres líneas)
-----------------------------

¿Cómo se puede hacer esto en CSS?

Respuestas:


1323

El posicionamiento relativo + absoluto es su mejor apuesta:

#header {
  position: relative;
  min-height: 150px;
}

#header-content {
  position: absolute;
  bottom: 0;
  left: 0;
}

#header, #header * {
  background: rgba(40, 40, 100, 0.25);
}
<div id="header">
  <h1>Title</h1>
  <div id="header-content">Some content</div>
</div>

Pero puede tener problemas con eso. Cuando lo probé, tuve problemas con los menús desplegables que aparecen debajo del contenido. Simplemente no es bonito.

Honestamente, para problemas de centrado vertical y, bueno, cualquier problema de alineación vertical con los elementos no es de altura fija, es más fácil usar tablas.

Ejemplo: ¿Puedes hacer este diseño HTML sin usar tablas?


44
En realidad encontré esa solución antes de preguntar aquí, pero de alguna manera olvidé agregar la posición: relativa; al encabezado div y el contenido siguió aterrizando en la parte inferior de la página. Gracias
kristof

15
Puede administrar su posición desplegable con la propiedad z-index para llevarla al frente. Recuerde que la propiedad del índice z funciona con elementos posicionados de manera relativa o absoluta. Además, no es correcto semánticamente hablando usar una tabla para lograr resultados de diseño.
Alejandro García Iglesias

1
En el caso del contenido de texto como se describe en el problema original, # header-content realmente debería ser un pelemento, o al menos unspan
Josh Burgess

2
¡No use tablas para datos no tabulares! En su lugar, use las propiedades de visualización de CSS display: table-cell, o table-row, o table. Nunca más necesitará usar tablas para un diseño puro.
Jeremy Moritz

1
¿La posición del encabezado es relativa a qué?
stack1

158

Usar posicionamiento CSS:

/* Creates a new stacking context on the header */
#header {
  position: relative;
}

/* Positions header-content at the bottom of header's context */
#header-content {
  position: absolute;
  bottom: 0;
}

Como señaló Cletus , debe identificar el contenido del encabezado para que esto funcione.

<span id="header-content">some header content</span>

<div style="height:100%; position:relative;">
    <div style="height:10%; position:absolute; bottom:0px;">bottom</div>
</div>

44
para su información ... esto causó que el contenido de mi encabezado colapsara su ancho, así que tuve que agregar un width = '100%'contenido de encabezado
dsdsdsdsd

2
@dsdsdsdsd También puede solucionarlo agregando display: block a # header-content.
Patrick McElhaney

1
@dsdsdsdsd La razón se debe a que los <span>elementos tienen display: inline;por defecto, lo que no ocupa todo el ancho del contenedor. La solución más adecuada sería cambiar el intervalo a a <div>, que es un elemento de bloque de forma predeterminada.
BadHorsie

1
O uno de <h1> - <h6> que también está bloqueado por defecto e identifica el texto como un encabezado, lo cual es útil para los motores de búsqueda, las tecnologías de asistencia y las personas que leen el código.
Patrick McElhaney

No funciona cuando el contenido en la parte inferior tiene una altura variable, lo que hace que se extienda fuera de los límites del contenedor.
Mozfet

126

Si no le preocupan los navegadores antiguos, use un flexbox.

El elemento padre necesita que su tipo de visualización esté configurado para flexionarse

div.parent {
  display: flex;
  height: 100%;
}

Luego establece el elemento secundario align-self en flex-end.

span.child {
  display: inline-block;
  align-self: flex-end;
}

Aquí está el recurso que solía aprender: http://css-tricks.com/snippets/css/a-guide-to-flexbox/


@bafromca, dos razones que no funcionan. 1: Use 'align-self' en lugar de align-items (mi culpa, he editado mi publicación original). 2: 100% de altura no funcionará a menos que el padre tenga altura.
Lee Irvine

No funcionó para mí, lo quiero en la parte inferior del contenedor, no al final de los artículos en el contenedor.
Mozfet

En 2020, esta debería ser la respuesta correcta: caniuse.com/#feat=flexbox
tonygatta

119

Yo uso estas propiedades y funciona!

#header {
  display: table-cell;
  vertical-align: bottom;
}

42
No es compatible con IE8 y versiones anteriores. Es compatible con IE9.
random_user_name

23
@cale_b Según caniuse.com , FUNCIONA en IE8.
Zach Lysobey

55
@ZachL Happenstance: estoy apoyando una aplicación heredada en IE8 para un cliente corporativo y esto de hecho funciona.
Daniel Szabo

44
@fguillen: probado en Chrome (v31) ahora mismo también. Trabaja allí también.
Daniel Szabo

55
table-cellrompe muchas cosas Al igual que el sistema de cuadrícula Bootstrap. col-md-12ya no te dará un div 100% de ancho.
Noah

65

Después de luchar con este mismo problema durante algún tiempo, finalmente descubrí una solución que cumple con todos mis requisitos:

  • No requiere que sepa la altura del contenedor.
  • A diferencia de las soluciones relativas + absolutas, el contenido no flota en su propia capa (es decir, se incrusta normalmente en el contenedor div).
  • Funciona en todos los navegadores (IE8 +).
  • Simple de implementar.

La solución solo toma una <div>, que llamo el "alineador":

CSS

.bottom_aligner {
    display: inline-block;
    height: 100%;
    vertical-align: bottom;
    width: 0px;
}

html

<div class="bottom_aligner"></div>
... Your content here ...

Este truco funciona creando un div alto y delgado, que empuja la línea de base de texto hacia el fondo del contenedor.

Aquí hay un ejemplo completo que logra lo que pedía el OP. He hecho el "bottom_aligner" grueso y rojo solo con fines de demostración.

CSS:

.outer-container {
  border: 2px solid black;
  height: 175px;
  width: 300px;
}

.top-section {
  background: lightgreen;
  height: 50%;
}

.bottom-section {
  background: lightblue;
  height: 50%;
  margin: 8px;
}

.bottom-aligner {
  display: inline-block;
  height: 100%;
  vertical-align: bottom;
  width: 3px;
  background: red;
}

.bottom-content {
  display: inline-block;
}

.top-content {
  padding: 8px;
}

HTML:

<body>
  <div class="outer-container">
    <div class="top-section">
      This text
      <br> is on top.
    </div>
    <div class="bottom-section">
      <div class="bottom-aligner"></div>
      <div class="bottom-content">
        I like it here
        <br> at the bottom.
      </div>
    </div>
  </div>
</body>

Alinear contenido inferior


Casi perfecto :) pero no permite saltos de línea automáticos.
Gaston Sanchez

No funciona si el contenedor externo puede desplazarse (overflow-y: auto). :(
ecraig12345

Supongo que marin: 8px debería ser margen: 8px
Graham Perrin

2
Esto también funciona si se coloca en una ::beforeregla, lo que elimina la necesidad de un elemento adicional. Usamos flex al final, pero esto es útil cuando no puedes.
Sheepy

Esta es una muy buena solución. Funciona solo si la heightcaja / contenedor y sus padres están configurados (en px o% o lo que sea).
BairDev

38

La forma moderna de hacerlo sería usar flexbox . Vea el ejemplo a continuación. Ni siquiera necesita envolverSome text...en ninguna etiqueta HTML, ya que el texto contenido directamente en un contenedor flexible está envuelto en un elemento flexible anónimo.

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

Si solo hay algo de texto y desea alinearlo verticalmente con la parte inferior del contenedor.

section {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  align-items: flex-end;           /* bottom of the box */
}
<section>Some text aligns to the bottom</section>


2
Necesitaba que mi elemento alineado con la parte inferior aún estuviera presente en el flujo de documentos, lo que no es posible cuando lo uso position:absolute;. ¡Esta solución funcionó perfectamente para mi caso!
Swen

1
Dentro de los componentes de reacción, esta es la solución correcta. La solución aceptada falla.
Soleil - Mathieu Prévot

1
Esta es la única solución que realmente funcionó para mí. Tal vez tenga que ver con React, como ha mencionado @Soleil ... No soy un experto en CSS, así que no estoy completamente seguro.
BK

Funciona perfectamente en el componente reaccionar
user1155773

25

Los elementos en línea o en bloque en línea se pueden alinear con la parte inferior de los elementos a nivel de bloque si la altura de línea del elemento padre / bloque es mayor que la del elemento en línea. *

margen:

<h1 class="alignBtm"><span>I'm at the bottom</span></h1>

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

* asegúrese de estar en modo estándar


25
display: flex;
align-items: flex-end;

2
Tenga en cuenta que flexbox no es compatible con navegadores antiguos.
AnthonyB

11
@AnthonyB - definir viejo? Tenemos que cambiar este registro como desarrolladores. La tecnología avanza, y lo viejo simplemente no sobrevive. IE9 y 10 tienen problemas con flex de lo que puedo ver, pero fueron lanzados en 2011 y 2012 respectivamente ... es 2017. Tenemos que dejar de lado estos navegadores obsoletos y rotos. Si no es por satisfacción visual, sino por seguridad y actualizaciones generales de software.
Tisch

3
@Tisch tiene toda la razón, como desarrolladores debemos usar tecnología decente y reciente. Pero simplemente advertiría sobre este problema de compatibilidad, para no sorprenderme.
AnthonyB

si el contenido debajo de <h1>está dentro de <p>o <div>lo usaría justify-content: space-between.
agapitocandemor

11

Simplemente puede lograr flex

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>


6

Si tiene varios elementos de altura dinámica, use los valores de visualización CSS de table y table-cell:

HTML

<html>
<body>

  <div class="valign bottom">
    <div>

      <div>my bottom aligned div 1</div>
      <div>my bottom aligned div 2</div>
      <div>my bottom aligned div 3</div>

    </div>
  </div>

</body>
</html>

CSS

html,
body {
  width: 100%;
  height: 100%;
}
.valign {
  display: table;
  width: 100%;
  height: 100%;
}
.valign > div {
  display: table-cell;
  width: 100%;
  height: 100%;
}
.valign.bottom > div {
  vertical-align: bottom;
}

He creado una demostración de JSBin aquí: http://jsbin.com/INOnAkuF/2/edit

La demostración también tiene un ejemplo de cómo centrar verticalmente la alineación utilizando la misma técnica.


5

Aquí hay otra solución usando flexbox pero sin usar flex-end para la alineación inferior. La idea es establecer margin-bottomen h1 en auto para empujar el contenido restante hacia abajo:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header h1 {
 margin-bottom:auto;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines) Header content (one or multiple lines)Header content (one or multiple lines) Header content (one or multiple lines)
</div>

También podemos hacer lo mismo con margin-top:autoel texto, pero en este caso debemos envolverlo dentro de divo span:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header span {
 margin-top:auto;
}
<div id="header">
  <h1>Header title</h1>
  <span>Header content (one or multiple lines)</span>
</div>


Perfecto! gracias
Grace Nikole

4

No necesitas absoluto + relativo para esto. Es muy posible usar la posición relativa tanto para el contenedor como para los datos. Así es como lo haces.

Suponga que la altura de sus datos será x. Su contenedor es relativo y el pie de página también es relativo. Todo lo que tienes que hacer es agregar a tus datos

bottom: -webkit-calc(-100% + x);

Sus datos siempre estarán en el fondo de su contenedor. Funciona incluso si tiene un contenedor con altura dinámica.

HTML será así

<div class="container">
  <div class="data"></div>
</div>

CSS será así

.container{
  height:400px;
  width:600px;
  border:1px solid red;
  margin-top:50px;
  margin-left:50px;
  display:block;
}
.data{
  width:100%;
  height:40px;
  position:relative;
   float:left;
  border:1px solid blue;
  bottom: -webkit-calc(-100% + 40px);
   bottom:calc(-100% + 40px);
}

Ejemplo en vivo aquí

Espero que esto ayude.


¿Puedes explicar lo que bottom: -webkit-calc(-100% + x);está haciendo?
mhatch

@hatch mantiene el pie de página en el fondo del contenedor.
Aditya Ponkshe

4

Aquí está la forma flexible de hacerlo. Por supuesto, IE8 no lo admite, ya que el usuario lo necesitaba hace 7 años. Dependiendo de lo que necesite apoyar, algunos de estos pueden eliminarse.

Aún así, sería bueno si hubiera una manera de hacer esto sin un contenedor externo, solo que el texto se alinee dentro de sí mismo.

#header {
    -webkit-box-align: end;
    -webkit-align-items: flex-end;
    -ms-flex-align: end;
    align-items: flex-end;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    height: 150px;
}

4

Una solución muy simple de una línea es agregar altura de línea al div, teniendo en cuenta que todo el texto del div irá al final.

CSS:

#layer{width:198px;
       height:48px;
       line-height:72px;
       border:1px #000 solid}
#layer a{text-decoration:none;}

HTML:

<div id="layer">
    <a href="#">text at div's bottom.</a>
</div>

tenga en cuenta que esta es una solución práctica y rápida cuando solo desea que el texto dentro de div baje, si necesita combinar imágenes y otras cosas, tendrá que codificar CSS un poco más complejo y receptivo


3

si pudiera establecer la altura del div de ajuste del contenido (# encabezado-contenido como se muestra en la respuesta de otros), en lugar de todo el # encabezado, tal vez también pueda probar este enfoque:

HTML

<div id="header">
    <h1>some title</h1>
    <div id="header-content">
        <span>
            first line of header text<br>
            second line of header text<br>
            third, last line of header text
        </span>
    </div>
</div>

CSS

#header-content{
    height:100px;
}

#header-content::before{
  display:inline-block;
  content:'';
  height:100%;
  vertical-align:bottom;
}

#header-content span{
    display:inline-block;
}

mostrar en codepen


3

Parece estar funcionando:

HTML: estoy en la parte inferior

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

3

Todas estas respuestas y ninguna funcionaron para mí ... No soy un experto en flexbox, pero esto fue razonablemente fácil de entender, es simple y fácil de entender y usar. Para separar algo del resto del contenido, inserte un div vacío y déjelo crecer para llenar el espacio.

https://jsfiddle.net/8sfeLmgd/1/

.myContainer {
  display: flex;
  height: 250px;
  flex-flow: column;
}

.filler {
  flex: 1 1;
}
<div class="myContainer">
  <div>Top</div>
  <div class="filler"></div>
  <div>Bottom</div>
</div>

Esto reacciona como se espera cuando el contenido del fondo no tiene un tamaño fijo y también cuando el contenedor no tiene un tamaño fijo.


3

He ideado una forma que es mucho más simple de lo que se ha mencionado.

Establece la altura del encabezado div. Luego dentro de eso, diseñe su H1etiqueta de la siguiente manera:

float: left;
padding: 90px 10px 11px

Estoy trabajando en un sitio para un cliente, y el diseño requiere que el texto esté en la parte inferior de un determinado div. He logrado el resultado usando estas dos líneas, y funciona bien. Además, si el texto se expande, el relleno seguirá siendo el mismo.


1
Causará que el contenido flote sobre otro contenido al cambiar el tamaño de las pantallas usando diseños receptivos.
Mozfet

2

Encontré esta solución basada en una plantilla de inicio de arranque predeterminada

/* HTML */

<div class="content_wrapper">
  <div class="content_floating">
    <h2>HIS This is the header<br>
      In Two Rows</h2>
    <p>This is a description at the bottom too</p> 
  </div>
</div>

/* css */

.content_wrapper{
      display: table;
      width: 100%;
      height: 100%; /* For at least Firefox */
      min-height: 100%;
    }

.content_floating{
  display: table-cell;
  vertical-align: bottom;
  padding-bottom:80px;

}

2
#header {
    height: 150px;
    display:flex;
    flex-direction:column;
}

.top{
    flex: 1;
}   

<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

#header {
    height: 250px;
    display:flex;
    flex-direction:column;
    background-color:yellow;
}

.top{
    flex: 1;
}
<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>


1
Esto provoca el cambio de tamaño del div superior. Lo que funciona para diseños de texto básicos, pero no funciona cuando las cosas tienen fondos y colores y tamaños a respetar.
Mozfet

0

probar con:

div.myclass { margin-top: 100%; }

intenta cambiar el% para arreglarlo. Ejemplo: 120% o 90% ... etc.


Funciona perfectamente bien con 1 conjunto de contenido, pero deberá ajustarse si el contenido cambia. Si se trata de contenido dinámico, ¡no lo uses!
Mike Graf

0

El sitio que acabo de hacer para un cliente solicitó que el texto del pie de página fuera un cuadro alto, con el texto en la parte inferior que logré esto con un simple relleno, debería funcionar para todos los navegadores.

<div id="footer">
  some text here
</div>
#footer {
  padding: 0 30px;
  padding-top: 60px;
  padding-bottom: 8px;
}

1
Su primera declaración padding: 0 30pxes un poco redundante, también puede haber puesto padding: 30pxlas otras 2 declaraciones.
Andrew

Absolutamente cierto, sin embargo sigo las prácticas de mi lugar de trabajo.
Nicki L. Hansen

66
¿En serio ?, eso parece una mala práctica. Simplemente use la taquigrafía, o sea explícito en todas partes. padding: 60px 30px 8px;, padding: 60px 30px 8px 30px;cuatro padding-reglas explícitas , o incluso la sugerencia de @ TheWaxMann son todas superiores, y estoy dispuesto y puedo argumentar eso ;-)
Zach Lysobey

-3

Un ejemplo perfecto de navegador cruzado es probablemente este aquí:

http://www.csszengarden.com/?cssfile=/213/213.css&page=0

La idea es mostrar el div en la parte inferior y también hacer que se quede allí. A menudo, el enfoque simple hará que el div adhesivo se desplace hacia arriba con el contenido principal.

El siguiente es un ejemplo mínimo totalmente funcional. Tenga en cuenta que no se requieren trucos de incrustación div. Las muchas BR son solo para forzar la aparición de una barra de desplazamiento:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #floater {
            background: yellow;
            height: 200px;
            width: 100%;
            position: fixed;
            bottom: 0px;
            z-index: 5;
            border-top: 2px solid gold;
        }

    </style>
</head>


<body>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>


    <div id="floater"></div>
</body>
</html>

Si se pregunta si su código podría no funcionar en IE, recuerde agregar la etiqueta DOCTYPE en la parte superior. Es crucial que esto funcione en IE. Además, esta debería ser la primera etiqueta y no debería aparecer nada encima.


28
Dado que está declarando su documento como estricto XHTML, también debe cerrar sus <br />etiquetas automáticamente ...
Amos M. Carpenter

77
@ KarlKildén si se refería al comentario de aaamos, definitivamente no es un comentario tonto: servir el documento anterior con su encabezado correctocontent-type provocaría que el navegador arroje un error de análisis xml.
Razor

77
Esta es una mala práctica! ¡Utiliza CSS en su lugar!
m93a

-4

Parece estar funcionando:

#content {
    /* or just insert a number with "px" if you're fighting CSS without lesscss.org :) */
    vertical-align: -@header_height + @content_height;

    /* only need it if your content is <div>,
     * if it is inline (e.g., <a>) will work without it */
    display: inline-block;
}

Usar menos hace que resolver acertijos de CSS se parezca mucho más a la codificación que a me gusta ... Me encanta el CSS. Es un verdadero placer cuando puede cambiar todo el diseño (sin romperlo :) simplemente cambiando un parámetro.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.