Comment aligner un élément flexible à droite?

682

Existe-t-il un moyen plus flexible pour aligner à droite "Contact" que pour l'utiliser position: absolute?

.main { display: flex; }
.a, .b, .c { background: #efefef; border: 1px solid #999; }
.b { flex: 1; text-align: center; }
.c { position: absolute; right: 0; }
<h2>With title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>
<h2>Without title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <!--<div class="b"><a href="#">Some title centered</a></div>-->
    <div class="c"><a href="#">Contact</a></div>
</div>

http://jsfiddle.net/vqDK9/

Mark Boulder
la source
2
vous pouvez utiliser float right, mais c'est la même chose ...! La meilleure façon est d'utiliser un tableau d'affichage avec alignement du texte.
Yohann Tilotti
Bien sûr, si c'est mieux. Cependant, j'ai
Mark Boulder
2
J'ai mis à jour votre violon jsfiddle.net/vqDK9/2
Yohann Tilotti
Voici au moins deux façons de le faire: stackoverflow.com/a/33856609/3597276
Michael Benjamin

Réponses:

455

Voici. Placez justify-content: space-betweensur le conteneur flexible.

.main { 
    display: flex; 
    justify-content: space-between;
  }
.a, .b, .c { background: #efefef; border: 1px solid #999; }
.b { text-align: center; }
<h2>With title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>
<h2>Without title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
<!--     <div class="b"><a href="#">Some title centered</a></div> -->
    <div class="c"><a href="#">Contact</a></div>
</div>

Kevin Suttle
la source
291
Oujustify-content: flex-end
BT
1
Essayez de définir la largeur de .c à 300 px. Le titre n'est plus centré. Alors oui, cela répond à la question, mais cela casse le design.
Agamemnus
23
Notez que cela ne fonctionne pas toujours comme vous pouvez vous y attendre, comme lorsqu'il y a un .c::afterpseudo-élément. D'après mon expérience, margin-left: auto;c'est la voie à suivre.
Volonté
13
Ouflex-flow: row-reverse;
jchook
8
Je ne vois pas que ce soit une bonne réponse si vous ne souhaitez pas aligner un seul élément dans un conteneur flexible.
Foxhoundn
1098

Une approche plus flexible consisterait à utiliser une automarge gauche (les éléments flex traitent les marges automatiques un peu différemment que lorsqu'ils sont utilisés dans un contexte de mise en forme de bloc).

.c {
    margin-left: auto;
}

Violon mis à jour:

.main { display: flex; }
.a, .b, .c { background: #efefef; border: 1px solid #999; }
.b { flex: 1; text-align: center; }
.c {margin-left: auto;}
<h2>With title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>
<h2>Without title</h2>
<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <!--<div class="b"><a href="#">Some title centered</a></div>-->
    <div class="c"><a href="#">Contact</a></div>
</div>
<h1>Problem</h1>
<p>Is there a more flexbox-ish way to right align "Contact" than to use position absolute?</p>

à la dérive
la source
2
Merci. Préféreriez-vous personnellement cela à la méthode de tableau d'affichage de Yohann Tilotti ci-dessus? Si oui, pourquoi?
Mark Boulder
4
@MarkBoulder: Pour des raisons de compatibilité, sa méthode est meilleure, mais si vous utilisez déjà flexbox, ma réponse aurait plus de sens.
dérive
4
@MarkBoulder: Ils accomplissent tous les deux la même chose dans ce cas. L'avantage serait d'avoir d' autres propriétés (et le comportement) associés à des éléments flexibles que l'approche de la table n'a pas ( flex, order, etc.).
dérive
3
Si vous ne pouvez pas envelopper les éléments et que vous devez flotter, dites les trois derniers à droite, ciblez le 3e du dernier uniquement avec ce margin-left: auto;style.
Daniel Sokolowski
2
@Justin l'a compris, pas besoin de les envelopper - je ne pouvais pas dans mon cas. La solution était de cibler le 1er des trois éléments uniquement avec margin-left: auto;.
Daniel Sokolowski
41

Si vous souhaitez utiliser FlexBox pour cela, vous devriez être en mesure, en faisant cela ( display: flexsur le conteneur, flex: 1sur les articles et text-align: rightsur .c):

.main { display: flex; }
.a, .b, .c {
    background: #efefef;
    border: 1px solid #999;
    flex: 1;
}
.b { text-align: center; }
.c { text-align: right; }

... ou alternativement (encore plus simple), si les articles n'ont pas besoin de se rencontrer, vous pouvez utiliser justify-content: space-betweensur le conteneur et supprimer text-aligncomplètement les règles:

.main { display: flex; justify-content: space-between; }
.a, .b, .c { background: #efefef; border: 1px solid #999; }

Voici une démo sur Codepen pour vous permettre d'essayer rapidement ce qui précède.

Nick F
la source
2
space-betweenétait exactement ce que je cherchais, merci!
Eddie Fletcher
Les frontières disparaissent lors de l'utilisation de la deuxième suggestion, comportement attendu? codepen.io/oshihirii/pen/RygKRd
user1063287
38

Vous pouvez également utiliser un remplissage pour remplir l'espace restant.

<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="filler"></div>
    <div class="c"><a href="#">Contact</a></div>
</div>

.filler{
    flex-grow: 1;
}

J'ai mis à jour la solution avec 3 versions différentes. Ceci en raison de la discussion sur la validité de l'utilisation d'un élément de remplissage supplémentaire. Si vous exécutez le code coupé, vous voyez que toutes les solutions font des choses différentes. Par exemple, si vous définissez la classe de remplissage sur l'élément b, cet élément remplira l'espace restant. Cela a l'avantage qu'il n'y a pas d'espace «mort» qui n'est pas cliquable.

<div class="mainfiller">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="filler"></div>
    <div class="c"><a href="#">Contact</a></div>
</div>

<div class="mainfiller">
    <div class="a"><a href="#">Home</a></div>
    <div class="filler b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>



<div class="main">
    <div class="a"><a href="#">Home</a></div>
    <div class="b"><a href="#">Some title centered</a></div>
    <div class="c"><a href="#">Contact</a></div>
</div>

<style>
.main { display: flex; justify-content: space-between; }
.mainfiller{display: flex;}
.filler{flex-grow:1; text-align:center}
.a, .b, .c { background: yellow; border: 1px solid #999; }
</style>

Arno
la source
3
Enfin quelqu'un qui comprend la flexbox
Kokodoko
9
@Kokodoko ouais, utiliser un autre élément html non sémantique pour déplacer un autre élément est le sommet de la compréhension de flexbox ...
Zanshin13
@ Zanshin13 Les autres réponses écrivent toutes tellement de CSS supplémentaires que vous pourriez aussi bien laisser de côté le conteneur flexible et coder le tout vous-même :)
Kokodoko
2
@Kokodoko justify-content: space-betweenest "tellement" css, sérieusement? Pas besoin de commentaires supplémentaires (mais si vous le souhaitez - bienvenue pour discuter). Cette réponse a le droit d'être ici, parce qu'il est une solution. Mais certainement pas optimal. Idk, vous n'avez peut-être pas remarqué mais la plupart des css d'une autre réponse sont des OP et les réponses réduisent en fait (un peu) la quantité de css de l'auteur. Cette réponse n'a pas moins de css que les autres (ne fonctionnera pas sans css d'OP - jsfiddle.net/63ma3b56 ). Mais il a encore un élément html.
Zanshin13
32

Ou vous pouvez simplement utiliser justify-content: flex-end

.main { display: flex; }
.c { justify-content: flex-end; }
Melchia
la source
3
L' justify-contentattribut est un attribut du flex-container, voir le cheatsheet flexy de Chris Coyer: css-tricks.com/snippets/css/a-guide-to-flexbox
Klaas van der Weij
1
C'est la seule solution sur cette page qui a fonctionné pour moi.
user2847376
19

Aussi facile que

.main {
    display: flex;
    flex-direction:row-reverse;
}
CESCO
la source
12

Ajoutez la classe CSS suivante à votre feuille de style:

.my-spacer {
    flex: 1 1 auto;
}

Placez un élément vide entre l'élément de gauche et l'élément que vous souhaitez aligner à droite:

<span class="my-spacer"></span>

andreisrob
la source
Pour ceux qui ne veulent pas simplement aligner un élément à droite, mais peuvent aligner un élément à gauche et en aligner un autre à droite (dans la même disposition flexible), c'est la voie à suivre!
Sensei James
8

Si vous avez besoin d'un élément à aligner à gauche (comme un en-tête) mais de plusieurs éléments à droite (comme 3 images), alors vous feriez quelque chose comme ceci:

h1 {
   flex-basis: 100%; // forces this element to take up any remaining space
}

img {
   margin: 0 5px; // small margin between images
   height: 50px; // image width will be in relation to height, in case images are large - optional if images are already the proper size
}

Voici à quoi cela ressemblera (seul le CSS relavent a été inclus dans l'extrait ci-dessus)

entrez la description de l'image ici

TetraDev
la source
6

'justification-contenu: flex-end' fonctionnait dans le conteneur de la boîte de prix.

.price-box {
    justify-content: flex-end;
}
Mohammad Adeel
la source
4

Je trouve que l'ajout de «justifier-contenu: flex-end» au conteneur flex résout le problème tandis que «justifier-contenu: espace entre» ne fait rien.

nuits
la source
2

Pour ceux qui utilisent Angular et Flex-Layout, utilisez ce qui suit sur le conteneur flex-item:

<div fxLayout="row" fxLayoutAlign="flex-end">

Voir les documents fxLayoutAlign ici et les documents fxLayout complets ici .

Lindauson
la source
0

Exemple de code basé sur la réponse de TetraDev

Images à droite:

* {
  outline: .4px dashed red;
}

.main {
  display: flex;
  flex-direction: row;
  align-items: center;
}

h1 {
  flex-basis: 100%;
}

img {
  margin: 0 5px;
  height: 30px;
}
<div class="main">
  <h1>Secure Payment</h1>
  <img src="https://i.stack.imgur.com/i65gn.png">
  <img src="https://i.stack.imgur.com/i65gn.png">
</div>

Images à gauche:

* {
  outline: .4px dashed red;
}

.main {
  display: flex;
  flex-direction: row;
  align-items: center;
}

h1 {
  flex-basis: 100%;
  text-align: right;
}

img {
  margin: 0 5px;
  height: 30px;
}
<div class="main">
  <img src="https://i.stack.imgur.com/i65gn.png">
  <img src="https://i.stack.imgur.com/i65gn.png">
  <h1>Secure Payment</h1>
</div>

1,21 gigawatts
la source