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>