Aligner un élément en bas avec flexbox


375

J'en ai divavec quelques enfants:

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

et je veux la mise en page suivante:

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

Indépendamment de la quantité de texte dans le pje veux coller le .buttontoujours en bas sans le retirer du flux. J'ai entendu dire que cela peut être réalisable avec Flexbox mais je ne peux pas le faire fonctionner.


7
Donnez-le-moi postition: absolute; bottom 0;?
Jonathan

12
@Jonathan le wrapper n'a pas de hauteur fixe. Si je le retire du flux, il chevaucherait le texte
supersize

2
@supersize old Q mais vous auriez pu donner le wrapper position:relative- c'est loufoque parce que je pense que c'est relatif par défaut mais vous l'avez SET pour que le positionnement absolu de l'enfant soit contenu. Puis bottom:0s'affleurer.
Jacksonkr

Jacksonkr a raison, c'est la MEILLEURE solution, d'autres sont trop longs, trop compliqués ou ne fonctionnent pas correctement
Barbz_YHOOL

2
@Jacksonkr la position par défaut d'un div n'est staticpas relative.
supersize

Réponses:


641

Vous pouvez utiliser les marges automatiques

Avant l'alignement via justify-contentet align-self, tout espace libre positif est distribué aux marges automatiques dans cette dimension.

Vous pouvez donc utiliser l'un d'eux (ou les deux):

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

Alternativement, vous pouvez créer l'élément avant la acroissance pour remplir l'espace disponible:

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


2
Pour moi, cela fonctionne dans Chrome, mais pas dans Safari sur iOS 10.2. Quelqu'un peut-il confirmer?
Matthew

@Oriol J'aime cette approche, mais pas l'effet secondaire de perdre des marges qui s'effondrent, que feriez-vous à ce sujet?
Neil

11
flex-grow a fonctionné pour moi. Voici comment je l'ai faithtml { height: 100%; } body { min-height: 100%; display: flex; flex-direction: column; } #site-content { flex: 1; }
protoEvangelion

2
Aussi une note latérale, n'oubliez pas height: 100%de l'élément parent dont vous essayez de pousser quelque chose vers le bas avecmargin-top: auto;
skolind

1
"tout espace libre positif est distribué aux marges automatiques dans cette dimension." ce sont des petites choses comme ça qui sont si élégantes, pour moi cette solution était 2 lignes de code basées sur votre réponse. merci :)
danjah

146

Vous pouvez utiliser display: flex pour positionner un élément vers le bas, mais je ne pense pas que vous souhaitiez utiliser flex dans ce cas, car cela affectera tous vos éléments.

Pour positionner un élément vers le bas à l'aide de flex, essayez ceci:

.container {
  display: flex;
}

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

Votre meilleur pari est de définir la position: absolue par rapport au bouton et de le définir bottom: 0, ou vous pouvez placer le bouton à l'extérieur du conteneur et utiliser un négatif transform: translateY(-100%)pour le mettre dans le conteneur comme ceci:

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

Vérifiez ce JSFiddle


6
si vous le souhaitez en bas, assurez-vous de définir la flex-direction sur colonne.
Viliami

3
Et si je ne peux pas fournir la hauteur?
Mark

Ce qui a fonctionné pour moi était juste: `` ''. contenu {display: flex; flex-direction: colonne; justifier-contenu: flex-end; } <div class = "content"> <a class="bottom"> Quelque chose </a> </div> ``
gsalgadotoledo

84

La solution avec align-self: flex-end;n'a pas fonctionné pour moi mais celle-ci l'a fait au cas où vous voudriez utiliser flex:

Résultat

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

Code

Remarque: Lorsque vous "exécutez l'extrait de code", vous devez faire défiler vers le bas pour voir le lien en bas.

.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
content est le conteneur de colonnes qu'il contient 2 autres conteneurs, avec justification-contenu: espace entre; vous dites à la flexbox de pousser le conteneur le plus loin possible (dans ce cas limité par la hauteur du conteneur de contenu)
ConquerorsHaki

ce n'est pas le vrai résultat, il y aura de l'espace entre chaque élément (d'où le nom)
Barbz_YHOOL

1
@Barbz_YHOOL Non, cela fonctionne si vous augmentez la hauteur du conteneur (voir l'exemple mis à jour)
Timo

1
Après beaucoup de recherches, c'est tout simplement parfait! Je vous remercie.
Rudy

1
Avec une petite modification, cette réponse a parfaitement fonctionné pour moi, merci
RealMJDev

2

Vous n'êtes pas sûr de Flexbox, mais vous pouvez le faire en utilisant la propriété position.

définir l' div position: relative élément parent et enfant qui pourrait être un <p>ou <h1>etc. définir position: absoluteet bottom: 0.

Exemple:

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

Code stylo ici.


1
position:fixedne fonctionnerait pas car alors il ne serait pas par rapport au récipient est. Peut - être que vous vouliez dire position:absolute?
Sensoray

1
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant pourquoi et / ou comment ce code répond à la question améliore sa valeur à long terme.
rollstuhlfahrer

1
Réponse mise à jour.
Sanjay Shr

1

entrez la description de l'image ici

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

Démo: https://codepen.io/ferittuncer/pen/YzygpWX


0

Lorsque vous réglez votre affichage sur Flex , vous pouvez simplement utiliser la flexpropriété pour marquer quel contenu peut s'agrandir et quel contenu ne peut pas.

Propriété 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

Essaye ça

.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

Je viens de trouver une solution à cela.

pour ceux qui ne sont pas satisfaits des réponses données, essayez cette approche avec 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>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.