Ich möchte A
B
und C
in der Mitte haben.
Wie kann ich D
dazu bringen, ganz nach rechts zu gehen?
VOR:
NACH DEM:
Was ist die beste Vorgehensweise dafür?
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>
Im Folgenden sind fünf Optionen zum Erreichen dieses Layouts aufgeführt:
flex: 1
Tragen Sie position: relative
auf den Flex-Container auf.
Übernehmen Sie position: absolute
auf Punkt D.
Jetzt ist dieser Artikel absolut im Flexbehälter positioniert.
Insbesondere wird Element D aus dem Dokumentenfluss entfernt, bleibt jedoch innerhalb der Grenzen des nächstgelegenen Vorfahren .
Verwenden Sie die CSS-Offset-Eigenschaften top
und right
, um 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 Bei dieser Methode werden einige Browser einen absolut positionierten Flex-Eintrag möglicherweise nicht vollständig aus dem normalen Fluss entfernen. Dies ändert die Ausrichtung auf eine nicht standardmäßige, unerwartete Weise. Weitere Details: In IE11 wird der absolut positionierte Flex-Artikel nicht aus dem normalen Fluss entfernt.
Mit einer Kombination aus auto
margin und einem neuen, unsichtbaren Flex-Element kann das Layout erreicht werden.
Der neue Flex-Artikel ist identisch mit Artikel D und befindet sich am gegenüberliegenden Ende (linker Rand).
Da die Flex-Ausrichtung auf der Verteilung des freien Raums basiert, ist das neue Element ein notwendiger Ausgleich, um die drei mittleren Felder horizontal zentriert zu halten. Das neue Element muss die gleiche Breite wie das vorhandene D-Element haben. Andernfalls werden die mittleren Felder nicht genau zentriert.
Das neue Element wird mit visibility: hidden
aus der Ansicht entfernt.
Zusamenfassend:
D
.auto
-Ränder, um A
, B
und C
zentriert zu halten, wobei beide D
-Elemente das gleiche Gleichgewicht von beiden Enden erzeugen.visibility: hidden
auf das Duplikat D
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>
Diese Methode ist ähnlich zu # 2, außer dass sie semantisch sauberer ist und die Breite von D
bekannt sein muss.
D
.::before
am Anfang des Containers.auto
-Ränder, um A
, B
und C
perfekt zentriert zu bleiben, wobei die Pseudo- und D
-Elemente an beiden Enden die gleiche Balance erzeugen.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>
flex: 1
zu linken und rechten Elementen hinzuBeginnen Sie mit Methode 2 oder 3 oben. Statt sich um die gleiche Breite für das linke und das rechte Element zu sorgen, um das gleiche Gleichgewicht zu erhalten, geben Sie einfach jedem flex: 1
. Dies zwingt sie beide dazu, den verfügbaren Platz zu verbrauchen, wodurch das mittlere Element zentriert wird.
Sie können dann display: flex
zu einzelnen Elementen hinzufügen, um deren Inhalt auszurichten.
NOTEüber die Verwendung dieser Methode mit min-height
: In Chrome, Firefox, Edge und möglicherweise anderen Browsern wird die Abkürzungsregel flex: 1
folgendermaßen zusammengefasst:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Diese Prozenteinheit (%) auf flex-basis
führt dazu, dass diese Methode abgebrochen wird, wenn min-height
für den Container verwendet wird. Dies liegt daran, dass in der Regel prozentuale Höhen für die untergeordneten Elemente eine explizite Einstellung der height
-Eigenschaft für das übergeordnete Element erfordern.
Dies ist eine alte CSS-Regel aus dem Jahr 1998 ( CSS Level 2 ), die in manchen Browsern bis zu einem gewissen Grad noch gültig ist. Für vollständige Details siehe hier und hier .
Hier ist ein Beispiel für das Problem in den Kommentaren von user2651804 :
#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 px
oder einfach gar nichts ( was die Spezifikation tatsächlich empfiehlt , obwohl zumindest einige der wichtigsten Browser aus irgendeinem Grund eine prozentuale Einheit angefügt 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>
Dies kann die sauberste und effizienteste Methode sein. Es besteht keine Notwendigkeit für absolute Positionierung, falsche Elemente oder andere Hacker.
Erstellen Sie einfach ein Raster mit mehreren Spalten. Positionieren Sie dann Ihre Artikel in der mittleren und unteren Spalte. Lassen Sie die erste Spalte einfach 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>
Sehr klare Frage. Ich konnte nicht anders, als die Antwort nach ein paar Stunden zu graben. Wir konnten das 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;
}
Wenn Sie eine Ausrichtung vornehmen möchten, können Sie einfach einen leeren Bereich anhängen und die drei untergeordneten Bereiche in diese Bereiche aufteilen.
Mit der Methode display:grid
können Sie einfach alle ul
Kinder in dieselbe Zelle einfügen und dann justify-self
einstellen:
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>
Ich habe erweitert auf Michael_B 's Antwort
.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>