Flexbox-Elemente in der Mitte und rechts ausrichten

146

Ich hätte gerne A Bund Cin der Mitte ausgerichtet.

Wie kann ich Dganz nach rechts gehen?

VOR:

Geben Sie hier die Bildbeschreibung ein

NACH DEM:

Geben Sie hier die Bildbeschreibung ein

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/

dunstig
quelle

Antworten:

212

Im Folgenden finden Sie fünf Optionen, um dieses Layout zu erreichen:

  • CSS-Positionierung
  • Flexbox mit unsichtbarem DOM-Element
  • Flexbox mit unsichtbarem Pseudoelement
  • Flexbox mit flex: 1
  • CSS-Rasterlayout

Methode 1: CSS-Positionierungseigenschaften

Auf den Flexbehälter position: relativeauftragen.

Auf position: absolutePunkt D anwenden .

Jetzt ist dieser Artikel absolut im Flex-Container positioniert.

Insbesondere wird Element D aus dem Dokumentfluss entfernt, bleibt jedoch innerhalb der Grenzen des nächstgelegenen positionierten Vorfahren .

Verwenden Sie die CSS - Offset - Eigenschaften topund rightdieses Element in Position zu bringen.

Eine Einschränkung dieser Methode besteht darin, dass einige Browser ein absolut positioniertes Flex-Element möglicherweise nicht vollständig aus dem normalen Ablauf entfernen. Dies ändert die Ausrichtung auf nicht standardmäßige, unerwartete Weise. Weitere Details: Absolut positioniertes Flex-Element wird in IE11 nicht aus dem normalen Fluss entfernt


Methode 2: Flex Auto Flex & Invisible Flex Item (DOM-Element)

Mit einer Kombination aus autoRändern und einem neuen, unsichtbaren Flex-Element kann das Layout erreicht werden.

Das neue Flex-Element ist identisch mit Element D und befindet sich am gegenüberliegenden Ende (am linken Rand).

Da die Flex-Ausrichtung auf der Verteilung des freien Speicherplatzes basiert, ist das neue Element ein notwendiges Gegengewicht, um die drei mittleren Felder horizontal zentriert zu halten. Das neue Element muss dieselbe Breite wie das vorhandene D-Element haben, da sonst die mittleren Felder nicht genau zentriert werden.

Das neue Element wird mit aus der Ansicht entfernt visibility: hidden.

Zusamenfassend:

  • Erstellen Sie ein Duplikat des DElements.
  • Platzieren Sie es am Anfang der Liste.
  • Flex - autoMargen zu halten A, Bund Czentriert ist , wobei beide DElemente von beiden Enden gleich Gleichgewicht zu schaffen.
  • Auf visibility: hiddendas Duplikat anwendenD


Methode 3: Flex Auto Margins & Invisible Flex Item (Pseudoelement)

Diese Methode ähnelt # 2, ist jedoch semantisch sauberer und die Breite von Dmuss bekannt sein.

  • Erstellen Sie ein Pseudoelement mit der gleichen Breite wie D.
  • Stellen Sie es am Anfang des Behälters mit ::before.
  • Flex - autoMargen zu halten A, Bund Cperfekt zentriert, und mit der Pseudo - DElemente von beiden Enden gleich Gleichgewicht zu schaffen.


Methode 4: Hinzufügen flex: 1zu linken und rechten Elementen

Beginnen Sie mit der obigen Methode Nr. 2 oder Nr. 3, anstatt sich um die gleiche Breite für das linke und das rechte Element zu sorgen, um das gleiche Gleichgewicht aufrechtzuerhalten. Geben Sie einfach jedes Element an flex: 1. Dadurch werden beide gezwungen, verfügbaren Speicherplatz zu belegen, wodurch das mittlere Element zentriert wird.

Sie können dann display: flexeinzelne Elemente hinzufügen , um deren Inhalt auszurichten.

HINWEIS zur Verwendung dieser Methode mit min-height: Derzeit in Chrome, Firefox, Edge und möglicherweise anderen Browsern lautet die Kurzschriftregel wieflex: 1folgt:

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

Diese prozentuale Einheit (%) bei flex-basisbewirkt, dass diese Methode unterbrochen wird, wenn min-heightsie für den Container verwendet wird. Dies liegt daran, dass für prozentuale Höhen der untergeordneten Elemente in der Regel eine explizite heightEigenschaftseinstellung für die übergeordneten Elemente erforderlich ist .

Dies ist eine alte CSS-Regel aus dem Jahr 1998 ( CSS Level 2 ), die in vielen Browsern bis zu einem gewissen Grad noch in Kraft ist. Für vollständige Details siehe hier und hier .

Hier ist eine Illustration des Problems, das in den Kommentaren von user2651804 veröffentlicht wurde :

Die Lösung besteht darin, die prozentuale Einheit nicht zu verwenden. Versuchen Sie es pxoder gar nichts ( was in der Spezifikation tatsächlich empfohlen wird , obwohl zumindest einige der wichtigsten Browser aus irgendeinem Grund eine prozentuale Einheit angehängt haben).


Methode 5: CSS-Rasterlayout

Dies kann die sauberste und effizienteste Methode sein. Es besteht keine Notwendigkeit für absolute Positionierung, gefälschte Elemente oder andere Hackerangriffe.

Erstellen Sie einfach ein Raster mit mehreren Spalten. Positionieren Sie dann Ihre Artikel in der mittleren und letzten Spalte. Lassen Sie einfach die erste Spalte leer.

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
quelle
1
Sehr schön, danke für die Erklärung! Ich denke, die neu hinzugefügten Codefragmente würden von einer Verkürzung des Beispieltextes profitieren, da aus der Ausgabe nicht ersichtlich ist, dass der Inhalt aufgrund eines kleinen Ansichtsfensters zentriert / nicht zentriert ist. Nur ich?
user2651804
"Das neue Element muss dieselbe Breite wie das vorhandene D-Element haben, da sonst die mittleren Felder nicht genau zentriert werden." - Das ist scheiße, dass es die gleiche Breite haben muss, aber Gott sei Dank für das CSS-Raster :)
Vucko
Bei Verwendung der Rastertechnik befinden sich die Elemente nicht im Totpunkt. Gibt es eine Möglichkeit, das Logoelement in der Mitte tot zu machen? imgur.com/a/SVg9xsj
J86
Nicht genug mit der Gitterlösung vertraut, obwohl sie wie ein Zauber wirkt und am saubersten ist. Eine Frage, die ich habe, ist, wie ich der mittleren Spalte, die nicht allen drei entspricht, mehr Platz geben kann.
Saba Ahang
5

Einfachster Weg

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

Wenn Sie es ausrichten möchten, können Sie einfach eine leere Spanne anhängen und die drei untergeordneten Spannen in diese aufteilen.

Ali Korkmaz
quelle
2
Können Sie eine kurze Demo zur Sicherung Ihrer Aussage bereitstellen?
Klewis
2

Die einfachste Lösung besteht darin, das Inhaltscenter für den übergeordneten Container zu begründen und dem ersten und letzten untergeordneten Element den automatischen Rand links zuzuweisen.

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

Mit dem display:gridAnsatz können Sie einfach alle ulKinder in dieselbe Zelle einfügen und dann Folgendes festlegen 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
quelle
0

Sehr klare Frage. Ich konnte nicht anders, als die Antwort nach ein paar Stunden Graben zu posten. Wir konnten dies mit Tabellen, Tabellenzellen, absoluten Positionen, Transformationen lösen, aber wir mussten es nur mit Flexbox tun :)

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

.center {
  margin: auto;
}

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

rgfx
quelle
8
Dadurch werden die mittleren Elemente nicht wirklich zentriert, da nur der verbleibende Raum berücksichtigt wird, nicht der gesamte Raum. codepen.io/anon/pen/QKGrRk
Michael Benjamin
@ Michael_B, dein Recht hat das nicht bemerkt, mein Schlechtes. Zurück zur Verwendung absoluter Positionen :( Vielleicht sollten Sie mit Ihrer hohen Wiederholungszahl ein Kopfgeld festlegen, um dies
endgültig zu
Kein Kopfgeld wird dem Flexbox-Modell ein neues Verhalten hinzufügen. Die von Michael_B gegebene Antwort ist so gut wie es nur geht ... heute.
Ason
0

Ich habe die Antwort von Michael_B erweitert

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

Hier mit Hilfe von SASS als Codepen

Yunzen
quelle
0

Inspiriert von der Methode Nr. 5: CSS- Rasterlayout von @Michal Benjamins Lösung und weil ich Rückenwind verwende und derzeit noch nicht standardmäßig auf alle Rasteroptionen zugreifen kann. Das scheint zu funktionieren:

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: Ich bin mir nicht sicher, ob es eine gute Idee ist, Flex und Grid so zu mischen!

Saba Ahang
quelle
1
Wenn Sie Grid und Flex nicht mischen, ist Justifty-Content eine CSS-Grid-Eigenschaft UND eine Flexbox-Eigenschaft (dasselbe gilt für align-self)
Temani Afif
-1

Die akzeptierte Antwort kann ein wenig geändert werden, da Sie Rastervorlagenbereiche verwenden und dies ohne gefälschtes Element tun können

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr
Repo
quelle
-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
quelle