Centrer et aligner les éléments flexbox à droite

147

Je voudrais avoir A Bet Caligné au milieu.

Comment puis-je Daller complètement à droite?

AVANT:

entrez la description de l'image ici

APRÈS:

entrez la description de l'image ici

ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  /* magic to throw to the right*/
}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>

https://jsfiddle.net/z44p7bsx/

brumeux
la source

Réponses:

214

Voici cinq options pour réaliser cette mise en page:

  • Positionnement CSS
  • Flexbox avec élément DOM invisible
  • Flexbox avec pseudo-élément invisible
  • Flexbox avec flex: 1
  • Disposition de la grille CSS

Méthode n ° 1: Propriétés de positionnement CSS

Appliquer position: relativesur le conteneur flexible.

Appliquer position: absoluteà l'article D.

Cet élément est désormais positionné de manière absolue dans le conteneur flexible.

Plus spécifiquement, l'élément D est supprimé du flux de documents mais reste dans les limites de l' ancêtre positionné le plus proche .

Utilisez les propriétés de décalage CSS topet rightpour déplacer cet élément en position.

Une mise en garde à cette méthode est que certains navigateurs peuvent ne pas supprimer complètement un élément flex positionné de manière absolue du flux normal. Cela modifie l'alignement d'une manière non standard et inattendue. Plus de détails: L'élément flex positionné de manière absolue n'est pas supprimé du flux normal dans IE11


Méthode n ° 2: marges automatiques flexibles et élément flexible invisible (élément DOM)

Avec une combinaison de automarges et un nouvel élément flexible invisible, la mise en page peut être obtenue.

Le nouvel élément flexible est identique à l'élément D et est placé à l'extrémité opposée (le bord gauche).

Plus précisément, étant donné que l'alignement flexible est basé sur la répartition de l'espace libre, le nouvel élément est un contrepoids nécessaire pour maintenir les trois cases du milieu centrées horizontalement. Le nouvel élément doit avoir la même largeur que l'élément D existant, sinon les cases du milieu ne seront pas précisément centrées.

Le nouvel élément est supprimé de la vue avec visibility: hidden.

En bref:

  • Créez un double de l' Délément.
  • Placez-le au début de la liste.
  • Utilisation fléchir les automarges pour maintenir A, Bet Ccentrée, avec les deux Déléments créant un équilibre égal des deux extrémités.
  • Appliquer visibility: hiddenau duplicataD


Méthode n ° 3: marges automatiques flexibles et élément flexible invisible (pseudo-élément)

Cette méthode est similaire à # 2, sauf qu'elle est plus sémantique et que la largeur de Ddoit être connue.

  • Créez un pseudo-élément de même largeur que D.
  • Placez-le au début du conteneur avec ::before.
  • Utilisez les automarges flexibles pour garder A, Bet Cparfaitement centré, le pseudo et les Déléments créant un équilibre égal des deux extrémités.


Méthode n ° 4: Ajouter flex: 1aux éléments de gauche et de droite

En commençant par la méthode n ° 2 ou n ° 3 ci-dessus, au lieu de vous soucier de la largeur égale des éléments gauche et droit pour maintenir un équilibre égal, donnez simplement chacun flex: 1. Cela les forcera tous les deux à consommer de l'espace disponible, centrant ainsi l'élément du milieu.

Vous pouvez ensuite ajouter display: flexdes éléments individuels afin d'aligner leur contenu.

REMARQUE sur l'utilisation de cette méthode avec min-height: Actuellement dans Chrome, Firefox, Edge et éventuellement d'autres navigateurs, la règle abrégéeflex: 1se résume à ceci:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

Cette unité de pourcentage (%) sur flex-basisprovoque la rupture de cette méthode lorsqu'elle min-heightest utilisée sur le conteneur. En effet, en règle générale, les hauteurs en pourcentage sur les enfants nécessitent un heightparamètre de propriété explicite sur le parent.

Il s'agit d'une ancienne règle CSS datant de 1998 ( CSS niveau 2 ) qui est toujours en vigueur dans de nombreux navigateurs à un degré ou à un autre. Pour plus de détails, voir ici et ici .

Voici une illustration du problème posté dans les commentaires de user2651804 :

La solution est de ne pas utiliser l'unité de pourcentage. Essayez pxou tout simplement rien du tout ( c'est ce que la spécification recommande en fait , malgré le fait qu'au moins certains des principaux navigateurs ont ajouté une unité de pourcentage pour une raison quelconque).


Méthode n ° 5: disposition de la grille CSS

C'est peut-être la méthode la plus propre et la plus efficace. Il n'y a pas besoin de positionnement absolu, de faux éléments ou d'autres piratages.

Créez simplement une grille avec plusieurs colonnes. Positionnez ensuite vos articles dans les colonnes du milieu et de la fin. En gros, laissez simplement la première colonne vide.

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>| true center |</span></p>

Michael Benjamin
la source
1
Très gentil, merci pour l'explication! Je suppose que les extraits de code nouvellement ajoutés gagneraient à raccourcir le texte d'exemple car il n'est pas réellement évident à partir de la sortie que le contenu est centré / non centré en raison de la petite fenêtre. Seulement moi?
user2651804
"Le nouvel élément doit avoir la même largeur que l'élément D existant, sinon les cases du milieu ne seront pas précisément centrées." - ça craint que ce soit la même largeur, mais merci dieu pour la grille CSS :)
Vucko
En utilisant la technique Grid, les éléments ne sont pas au point mort, y a-t-il un moyen de faire en sorte que l'élément du logo soit mort au centre? imgur.com/a/SVg9xsj
J86
Pas assez familier avec la solution de grille bien qu'elle fonctionne comme un charme et soit la plus propre. Une question que je me pose est de savoir comment donner plus d'espace à la colonne du milieu pas égal aux trois?
Saba Ahang
5

Le moyen le plus simple

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>

Razib Hossain
la source
2

Si vous souhaitez l'aligner, vous pouvez simplement attacher une travée vide et diviser les trois travées enfants en elles.

Ali Korkmaz
la source
2
pouvez-vous fournir une courte démonstration pour sauvegarder votre déclaration?
klewis le
2

La solution la plus simple sera de justifier le centre de contenu au conteneur parent et de donner une marge gauche automatique au premier et au dernier élément enfant.

ul {
  display:flex;
  justify-content:center;
}


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>

Suhail AKhtar
la source
1

En utilisant l' display:gridapproche, vous pouvez simplement mettre tous les ulenfants dans la même cellule, puis définir justify-self:

ul {
  display: grid;
}

ul > * {
  grid-column-start: 1;
  grid-row-start: 1;
  justify-self:center;
}

ul > *:last-child {
  justify-self: right;
}

/* Make Fancy */
li {
  display:inline-block;
  margin: 1px;
  padding: 5px;
  background: #bbb;
}
<ul>
  <span>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  </span>
  <li>D</li>
</ul>

Steven Spungin
la source
0

Question très claire. Je n'ai pas pu m'empêcher de poster la réponse après quelques heures de fouille. Nous pourrions résoudre ce problème avec des tableaux, des cellules de table, des positions absolues, des transformations, mais nous devions le faire avec flexbox :)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd

rgfx
la source
8
Cela ne centre pas vraiment les éléments du milieu, car il ne prend en compte que l' espace restant , pas l' espace entier . codepen.io/anon/pen/QKGrRk
Michael Benjamin
@Michael_B, votre droit ne l'a pas remarqué, mon mal. De retour à l'utilisation des positions absolues: (Peut-être qu'avec votre haute répétition, vous devriez définir une prime pour résoudre ce problème pour de bon. Je le ferais mais j'ai une très faible répétition, encore plus basse maintenant, essayant de vous aider.
rgfx
Aucune prime ne va ajouter un nouveau comportement au modèle flexbox, la réponse donnée par Michael_B est aussi bonne qu'elle l'est ... aujourd'hui.
Ason
0

J'ai développé la réponse de Michael_B

.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
  flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
  justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
  justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
  margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
  flex: 1;
  justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
  flex: 1;
  justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
  margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
  content: '';
  flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
  content: '';
  flex: 1;
}

[class*=center-flex] {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
  display: flex;
}
li {
  padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
  <span>
    <li>Accusamus</li>
    <li>Porro</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

<br><br>
1 of 1
<ul class="center-flex__1-of-1">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

Ici avec l'aide de SASS comme codepen

yunzen
la source
0

Inspiré de la méthode # 5: CSS Grid Layout de la solution de @Michal Benjamin et parce que j'utilise Tailwind et que je n'ai pas encore accès à toutes les options de la grille par défaut. Cela semble fonctionner:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS: Je ne sais pas si mélanger le flex et la grille comme ça est une bonne idée!

Saba Ahang
la source
1
vous ne mélangez pas grille et flex, justifty-content est une propriété de grille CSS ET une propriété flexbox (même chose pour align-self)
Temani Afif
-1

La réponse acceptée peut être un peu modifiée car vous pouvez utiliser des zones de modèle de grille et le faire sans faux élément

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr
repo
la source
-1
ul { 
  padding: 0; 
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  position:absolute;
  right:10px;

}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
SUDHIR KUMAR
la source