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.

surdimensionné
la source
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 */

Oriol
la source
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

Roumelis George
la source
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>

Timo
la source
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.

Sanjay Shr
la source
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

ferit
la source
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>

Tomas Vancoillie
la source
-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>

mohxn ayaz
la source
-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>
aj go
la source