Allinea un elemento in basso con la flexbox


375

Ho un divcon alcuni bambini:

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

e voglio il seguente layout:

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

Indipendentemente da quanto testo ci sia, pvoglio incollare .buttonsempre il fondo senza toglierlo dal flusso. Ho sentito che questo può essere realizzato con Flexbox ma non riesco a farlo funzionare.


7
Darlo e basta postition: absolute; bottom 0;?
Jonathan,

12
@Jonathan il wrapper non ha un'altezza fissa. Se lo togliessi dal flusso, si sovrapporterebbe al testo
sostituire il

2
@supersize vecchio Q ma avresti potuto dare il wrapper position:relative- è sciocco perché penso che sia relativo di default ma lo hai impostato in modo da contenere il posizionamento assoluto del bambino. Quindi bottom:0si adatta a filo.
Jacksonkr

Jacksonkr ha ragione, questa è la soluzione MIGLIORE, altri sono troppo lunghi, troppo contorti o non funzionano nel modo giusto
Barbz_YHOOL

2
@Jacksonkr la posizione predefinita di un div staticnon lo è relative.
Sostituisci il

Risposte:


641

È possibile utilizzare i margini automatici

Prima dell'allineamento tramite justify-contente align-self, qualsiasi spazio libero positivo viene distribuito ai margini automatici in quella dimensione.

Quindi puoi usare uno di questi (o entrambi):

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

In alternativa, puoi creare l'elemento prima della acrescita per riempire lo spazio disponibile:

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


2
Per me, questo funziona in Chrome, ma non in Safari su iOS 10.2. Qualcuno può confermare?
Matteo,

@Oriol Mi piace questo approccio, ma non l'effetto collaterale della perdita dei margini di collasso, cosa faresti?
Neil,

11
flex-grow ha funzionato per me. Ecco come l'ho fattohtml { height: 100%; } body { min-height: 100%; display: flex; flex-direction: column; } #site-content { flex: 1; }
protoEvangelion

2
Anche una nota a height: 100%margin-top: auto;
margine

1
"qualsiasi spazio libero positivo viene distribuito ai margini automatici in quella dimensione." sono piccole cose come questa che sono così eleganti, per me questa soluzione era di 2 righe di codice basate sulla tua risposta. grazie :)
danjah

146

Puoi usare display: flex per posizionare un elemento in basso, ma non credo che tu voglia usare flex in questo caso, poiché influenzerà tutti i tuoi elementi.

Per posizionare un elemento verso il basso usando flex, prova questo:

.container {
  display: flex;
}

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

La tua scommessa migliore è impostare la posizione: assoluta sul pulsante e impostarla su bottom: 0, oppure puoi posizionare il pulsante fuori dal contenitore e usare il negativo transform: translateY(-100%)per portarlo nel contenitore in questo modo:

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

Controlla questo JSFiddle


6
se lo vuoi in basso, assicurati di impostare la direzione flessibile su colonna.
Viliami,

3
Cosa succede se non riesco a fornire l'altezza?
Segna

Ciò che ha funzionato per me è stato solo: ``. content {display: flex; direzione flessibile: colonna; contenuti giustificati: flex-end; } <div class = "content"> <a class="bottom"> Something </a> </div> `` `
gsalgadotoledo

84

La soluzione con align-self: flex-end;non ha funzionato per me, ma questa ha funzionato nel caso in cui si desideri utilizzare flex:

Risultato

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

Codice

Nota: quando "esegui lo snippet di codice" devi scorrere verso il basso per vedere il link in fondo.

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


1
il contenuto è il contenitore della colonna che contiene altri 2 contenitori, con giustificazione-contenuto: spazio-in mezzo; dici al flexbox di allontanare il più possibile il contenitore l'uno dall'altro (in questo caso limitato dall'altezza del contenitore del contenuto)
ConquerorsHaki

non è il risultato reale, avrà spazio tra ogni elemento (da qui il nome)
Barbz_YHOOL

1
@Barbz_YHOOL No, funziona se aumenti l'altezza del contenitore (vedi esempio aggiornato)
Timo

1
Dopo aver cercato molto, questo è semplicemente perfetto! Grazie.
Rudy,

1
Con una piccola modifica, questa risposta ha funzionato perfettamente per me, grazie
RealMJDev

2

Non sei sicuro di flexbox ma puoi farlo usando la proprietà position.

imposta div position: relative l'elemento parent e child che potrebbe essere un set <p>o <h1>etc .. position: absolutee bottom: 0.

Esempio:

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

Penna codice qui.


1
position:fixednon funzionerebbe perché allora non sarebbe relativo al contenitore in cui si trova. Forse intendevi position:absolute?
Sensoray,

1
Mentre questo codice può rispondere alla domanda, fornendo un contesto aggiuntivo riguardo al perché e / o al modo in cui questo codice risponde alla domanda migliora il suo valore a lungo termine.
rollstuhlfahrer,

1
Risposta aggiornata.
Sanjay Shr,

1

inserisci qui la descrizione dell'immagine

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

Demo: https://codepen.io/ferittuncer/pen/YzygpWX


0

Quando si imposta la visualizzazione su flessibile , è possibile semplicemente utilizzare la flexproprietà per contrassegnare quali contenuti possono crescere e quali no.

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


-1

Prova questo

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


-1

Ho appena trovato una soluzione per questo.

per coloro che non sono soddisfatti delle risposte fornite possono provare questo approccio 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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.