Alinear un elemento al fondo con flexbox

375

Tengo un divcon algunos niños:

<div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some more or less text</p>
  <a href="/" class="button">Click me</a>
</div>

y quiero el siguiente diseño:

 -------------------
|heading 1          |
|heading 2          | 
|paragraph text     |
|can have many      |
|rows               |
|                   |
|                   |
|                   | 
|link-button        |
 -------------------

Independientemente de cuánto texto hay en el p, quiero pegar .buttonsiempre en la parte inferior sin sacarlo del flujo. He oído que esto se puede lograr con Flexbox, pero no puedo hacer que funcione.

de gran tamaño
fuente
77
Solo dalo postition: absolute; bottom 0;?
Jonathan
12
@ Jonathan el contenedor no tiene una altura fija. Si lo saco del flujo, se superpondría con el texto
tamaño
2
@supersize Q antiguo, pero podría haber dado el contenedor position:relative: es una tontería porque creo que es relativo por defecto, pero lo ha SET para que se contenga el posicionamiento absoluto del niño. Luego bottom:0quedará al ras.
Jacksonkr
Jacksonkr es correcto, esta es la mejor solución, otros son demasiado largo, demasiado convoluida o no funciona de la manera correcta
Barbz_YHOOL
2
@Jacksonkr, la posición predeterminada de un div staticno lo es relative.
supersize

Respuestas:

641

Puedes usar márgenes automáticos

Antes de la alineación a través de justify-contenty align-self, cualquier espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión.

Entonces puede usar uno de estos (o ambos):

p { margin-bottom: auto; } /* Push following elements to the bottom */
a { margin-top: auto; } /* Push it and following elements to the bottom */

Alternativamente, puede hacer el elemento antes del acrecimiento para llenar el espacio disponible:

p { flex-grow: 1; } /* Grow to fill available space */

Oriol
fuente
2
Para mí, esto funciona en Chrome, pero no en Safari en iOS 10.2. ¿Alguien puede confirmar?
Matthew
@Oriol Me gusta este enfoque, pero no el efecto secundario de perder los márgenes de colapso, ¿qué harías al respecto?
Neil
11
flex-grow funcionó para mí. Así es como lo hicehtml { height: 100%; } body { min-height: 100%; display: flex; flex-direction: column; } #site-content { flex: 1; }
protoEvangelion
2
También una nota al margen, recuerde height: 100%el elemento principal con el que está tratando de empujar algo hacia abajomargin-top: auto;
skolind el
1
"cualquier espacio libre positivo se distribuye a los márgenes automáticos en esa dimensión". Son pequeñas cosas como esta las que son tan elegantes, para mí esta solución fue 2 líneas de código basadas en su respuesta. gracias :)
danjah
146

Puede usar display: flex para colocar un elemento en la parte inferior, pero no creo que quiera usar flex en este caso, ya que afectará a todos sus elementos.

Para colocar un elemento en la parte inferior usando flex intente esto:

.container {
  display: flex;
}

.button {
  align-self: flex-end;
}

Su mejor opción es establecer la posición: absoluta para el botón y establecerla bottom: 0, o puede colocar el botón fuera del contenedor y usar negativotransform: translateY(-100%) para traerlo al contenedor de esta manera:

.content {
    height: 400px;
    background: #000;
    color: #fff;
}
.button {
    transform: translateY(-100%);
    display: inline-block;
}

Comprueba este JSFiddle

Roumelis George
fuente
66
si lo desea en la parte inferior, asegúrese de establecer la dirección de flexión en la columna.
Viliami
3
¿Qué pasa si no puedo proporcionar la altura?
Mark
Lo que funcionó para mí fue simplemente: `` ``. contenido {display: flex; dirección flexible: columna; justify-content: flex-end; } <div class = "content"> <a class="bottom"> Algo </a> </div> `` `
gsalgadotoledo
84

La solución con align-self: flex-end;no funcionó para mí, pero esta sí lo hizo en caso de que quiera usar flex:

Resultado

 -------------------
|heading 1          |
|heading 2          | 
|paragraph text     |
|                   |
|                   |
|                   | 
|link button        |
 -------------------

Código

Nota: Al "ejecutar el fragmento de código", debe desplazarse hacia abajo para ver el enlace en la parte inferior.

.content {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  height: 300px;
}

.content .upper {
  justify-content: normal;
}

/* Just to show container boundaries */
.content .upper, .content .bottom, .content .upper > * {
  border: 1px solid #ccc;
}
<div class="content">
  <div class="upper">
	  <h1>heading 1</h1>
	  <h2>heading 2</h2>
	  <p>paragraph text</p>
  </div>

  <div class="bottom">
	  <a href="/" class="button">link button</a>
  </div>
</div>

Timo
fuente
1
content es el contenedor de la columna que contiene otros 2 contenedores, con justify-content: space-between; le dice a la caja flexible que separe el contenedor lo más posible (en este caso, limitado por la altura del contenedor de contenido)
ConquerorsHaki
ese no es el resultado real, tendrá espacio entre cada elemento (de ahí el nombre)
Barbz_YHOOL
1
@Barbz_YHOOL No, funciona si aumenta la altura del contenedor (ver ejemplo actualizado)
Timo
1
Después de buscar mucho, ¡esto es perfecto! Gracias.
Rudy
1
Con una pequeña modificación, esta respuesta funcionó perfectamente para mí, gracias
RealMJDev
2

No estoy seguro acerca de flexbox, pero puede hacerlo usando la propiedad de posición.

establece div position: relative el elemento primario y secundario que puede ser un <p>o <h1>etc. establece position: absolutey bottom: 0.

Ejemplo:

index.html

<div class="parent">
  <p>Child</p>
</div>

style.css

.parent {
  background: gray;
  width: 10%;
  height: 100px;    
  position: relative;
}
p {
  position: absolute;
  bottom: 0;
}

Código de pluma aquí.

Sanjay Shr
fuente
1
position:fixedno funcionaría porque entonces no sería relativo al contenedor en el que se encuentra. ¿Quizás quiso decir position:absolute?
Sensoray
1
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a por qué y / o cómo responde la pregunta mejora su valor a largo plazo.
rollstuhlfahrer
1
Respuesta actualizada
Sanjay Shr
1

ingrese la descripción de la imagen aquí

<section style="display:flex; flex-wrap:wrap;">
    <div style="display:flex; flex-direction:column; flex:1;">
        <button style="margin-top: auto;"/>
    </div>
    <div style="display:flex; flex-direction:column; flex:1;">
        <button style="margin-top: auto;"/>
    </div>
</section>

Demostración: https://codepen.io/ferittuncer/pen/YzygpWX

fermentar
fuente
0

Al configurar su pantalla para que se flexione , simplemente puede usar la flexpropiedad para marcar qué contenido puede crecer y qué contenido no.

Propiedad Flex

div.content {
 height: 300px;
 display: flex;
 flex-direction: column;
}

div.up {
  flex: 1;
}

div.down {
  flex: none;
}
<div class="content">
  <div class="up">
    <h1>heading 1</h1>
    <h2>heading 2</h2>
    <p>Some more or less text</p>
  </div>

  <div class="down">
    <a href="/" class="button">Click me</a>
  </div>
</div>

Tomás Vancoillie
fuente
-1

Prueba esto

.content {
      display: flex;
      flex-direction: column;
      height: 250px;
      width: 200px;
      border: solid;
      word-wrap: break-word;
    }

   .content h1 , .content h2 {
     margin-bottom: 0px;
    }

   .content p {
     flex: 1;
    }
   <div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some more or less text</p>
  <a href="/" class="button">Click me</a>
</div>

mohxn ayaz
fuente
-1

Acabo de encontrar una solución para esto.

para aquellos que no están satisfechos con las respuestas dadas, pueden probar este enfoque con flexbox

CSS

    .myFlexContainer {
        display: flex;
        width: 100%;
    }

    .myFlexChild {
        width: 100%;
        display: flex;

        /* 
         * set this property if this is set to column by other css class 
         *  that is used by your target element 
         */
        flex-direction: row;

        /* 
         * necessary for our goal 
         */
        flex-wrap: wrap;
        height: 500px;
    }

    /* the element you want to put at the bottom */
    .myTargetElement {
        /*
         * will not work unless flex-wrap is set to wrap and 
         * flex-direction is set to row
         */
        align-self: flex-end;
    }

HTML

    <div class="myFlexContainer">
        <div class="myFlexChild">
            <p>this is just sample</p>
            <a class="myTargetElement" href="#">set this to bottom</a>
        </div>
    </div>
aj ir
fuente