Poniżej znajduje się pięć opcji osiągnięcia tego układu:
- Pozycjonowanie CSS
- Flexbox z niewidocznym elementem DOM
- Flexbox z niewidocznym pseudoelementem
- Flexbox z
flex: 1
- Układ siatki CSS
Metoda nr 1: Właściwości pozycjonowania CSS
Zastosuj position: relative
do pojemnika elastycznego.
Zastosuj position: absolute
do pozycji D.
Teraz ten przedmiot jest absolutnie umieszczony w pojemniku elastycznym.
Mówiąc dokładniej, element D jest usuwany z przepływu dokumentów, ale pozostaje w granicach najbliższego umieszczonego przodka .
Użyj właściwości przesunięcia CSS top
i right
przesuń ten element na miejsce.
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>
Jedynym zastrzeżeniem do tej metody jest to, że niektóre przeglądarki mogą nie usunąć całkowicie pozycjonowanego elementu elastycznego z normalnego przepływu. Zmienia to ustawienie w niestandardowy, nieoczekiwany sposób. Więcej szczegółów: Absolutnie pozycjonowany element elastyczny nie jest usuwany z normalnego przepływu w IE11
Metoda nr 2: Flex Auto Margins & Invisible Flex Item (element DOM)
Dzięki połączeniu auto
marginesów i nowego, niewidocznego elementu elastycznego można uzyskać układ.
Nowy element elastyczny jest identyczny z elementem D i jest umieszczony na przeciwległym końcu (lewa krawędź).
Mówiąc dokładniej, ponieważ wyrównanie flex jest oparte na rozkładzie wolnej przestrzeni, nowy element jest niezbędną przeciwwagą, aby trzy środkowe pola były wyśrodkowane w poziomie. Nowy element musi mieć taką samą szerokość jak istniejący element D, w przeciwnym razie środkowe pola nie będą dokładnie wyśrodkowane.
Nowy element jest usuwany z widoku za pomocą visibility: hidden
.
W skrócie:
- Utwórz kopię
D
elementu.
- Umieść go na początku listy.
- Zastosowanie wyginają
auto
marże utrzymują A
, B
i C
skupione, ze oba D
elementy tworząc równowagę z obu końców.
- Zastosuj
visibility: hidden
do duplikatuD
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>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Metoda nr 3: Flex Auto Margins & Invisible Flex Item (pseudoelement)
Ta metoda jest podobna do # 2, z wyjątkiem tego, że jest bardziej przejrzysta semantycznie, a szerokość D
musi być znana.
- Utwórz pseudoelement o tej samej szerokości co
D
.
- Umieść go na początku pojemnika z
::before
.
- Użyj flex
auto
marże zachować A
, B
i C
całkiem w środku, z pseudo i D
elementy tworząc równowagę z obu końców.
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>
Metoda nr 4: Dodaj flex: 1
do lewej i prawej pozycji
Zaczynając od metody nr 2 lub nr 3 powyżej, zamiast martwić się o równą szerokość lewego i prawego elementu, aby zachować równą równowagę, po prostu podaj każdy z nich flex: 1
. Zmusi to ich obu do wykorzystania dostępnej przestrzeni, w ten sposób wyśrodkowując środkowy element.
Następnie możesz dodać display: flex
poszczególne elementy, aby wyrównać ich zawartość.
UWAGA dotycząca korzystania z tej metody w przypadku min-height
: Obecnie w Chrome, Firefox, Edge i prawdopodobnie innych przeglądarkach reguła skrótuflex: 1
sprowadza się do tego:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Ta jednostka procentowa (%) na flex-basis
powoduje zerwanie tej metody, gdy min-height
jest używana na kontenerze. Dzieje się tak, ponieważ z reguły procentowe wysokości elementów potomnych wymagają jawnego height
ustawienia właściwości elementu nadrzędnego.
Jest to stara reguła CSS z 1998 roku ( CSS poziom 2 ), która do pewnego stopnia nadal obowiązuje w wielu przeglądarkach. Aby uzyskać szczegółowe informacje, zobacz tutaj i tutaj .
Oto ilustracja problemu opublikowanego w komentarzach przez użytkownika2651804 :
#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>
Rozwiązaniem jest niestosowanie jednostki procentowej. Spróbuj px
lub po prostu nic ( co tak naprawdę zaleca specyfikacja , pomimo faktu, że przynajmniej niektóre z głównych przeglądarek dodały jednostkę procentową z dowolnego powodu).
#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-basis: 0;
}
#flex-container::after {
content: "";
flex: 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>
Metoda nr 5: Układ siatki CSS
To może być najczystsza i najbardziej wydajna metoda. Nie ma potrzeby pozycjonowania absolutnego, fałszywych elementów ani innych hakerów.
Po prostu utwórz siatkę z wieloma kolumnami. Następnie umieść przedmioty w środkowej i końcowej kolumnie. Zasadniczo zostaw pierwszą kolumnę pustą.
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; }
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>