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: relative
auftragen.
Auf position: absolute
Punkt 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 top
und right
dieses Element in Position zu bringen.
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
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 auto
Rä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
D
Elements.
- Platzieren Sie es am Anfang der Liste.
- Flex -
auto
Margen zu halten A
, B
und C
zentriert ist , wobei beide D
Elemente von beiden Enden gleich Gleichgewicht zu schaffen.
- Auf
visibility: hidden
das Duplikat anwendenD
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
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;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Methode 3: Flex Auto Margins & Invisible Flex Item (Pseudoelement)
Diese Methode ähnelt # 2, ist jedoch semantisch sauberer und die Breite von D
muss bekannt sein.
- Erstellen Sie ein Pseudoelement mit der gleichen Breite wie
D
.
- Stellen Sie es am Anfang des Behälters mit
::before
.
- Flex -
auto
Margen zu halten A
, B
und C
perfekt zentriert, und mit der Pseudo - D
Elemente von beiden Enden gleich Gleichgewicht zu schaffen.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
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;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Methode 4: Hinzufügen flex: 1
zu 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: flex
einzelne 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: 1
folgt:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Diese prozentuale Einheit (%) bei flex-basis
bewirkt, dass diese Methode unterbrochen wird, wenn min-height
sie für den Container verwendet wird. Dies liegt daran, dass für prozentuale Höhen der untergeordneten Elemente in der Regel eine explizite height
Eigenschaftseinstellung 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 :
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Die Lösung besteht darin, die prozentuale Einheit nicht zu verwenden. Versuchen Sie es px
oder 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).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
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>
Einfachster Weg
quelle
Wenn Sie es ausrichten möchten, können Sie einfach eine leere Spanne anhängen und die drei untergeordneten Spannen in diese aufteilen.
quelle
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.
quelle
Mit dem
display:grid
Ansatz können Sie einfach alleul
Kinder in dieselbe Zelle einfügen und dann Folgendes festlegenjustify-self
:quelle
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 :)
http://codepen.io/rgfx/pen/BLorgd
quelle
Ich habe die Antwort von Michael_B erweitert
Hier mit Hilfe von SASS als Codepen
quelle
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:
PS: Ich bin mir nicht sicher, ob es eine gute Idee ist, Flex und Grid so zu mischen!
quelle
Die akzeptierte Antwort kann ein wenig geändert werden, da Sie Rastervorlagenbereiche verwenden und dies ohne gefälschtes Element tun können
quelle
quelle