Berikut adalah lima opsi untuk mencapai tata letak ini:
- Pemosisian CSS
- Flexbox dengan Elemen DOM yang Tak Terlihat
- Flexbox dengan Elemen Pseudo-Tak Terlihat
- Flexbox dengan
flex: 1
- Layout Kotak CSS
Metode # 1: Properti Pemosisian CSS
Oleskan position: relative
ke wadah fleksibel.
Berlaku position: absolute
untuk item D.
Sekarang item ini benar-benar diposisikan dalam wadah fleksibel.
Lebih khusus, item D dihapus dari aliran dokumen tetapi tetap dalam batas leluhur diposisikan terdekat .
Gunakan properti offset CSS top
dan right
untuk memindahkan elemen ini ke posisi.
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>
Satu peringatan untuk metode ini adalah bahwa beberapa browser mungkin tidak sepenuhnya menghapus item fleksibel yang diposisikan benar-benar dari aliran normal. Ini mengubah perataan dengan cara yang tidak standar dan tidak terduga. Lebih detail: Item fleksibel yang diposisikan benar-benar tidak dihapus dari aliran normal di IE11
Metode # 2: Margin Otomatis Flex & Item Flex Tak Terlihat (elemen DOM)
Dengan kombinasi auto
margin dan item fleksibel baru, tata letak dapat dicapai.
Item flex baru identik dengan item D dan ditempatkan di ujung yang berlawanan (tepi kiri).
Lebih khusus lagi, karena penyejajaran flex didasarkan pada distribusi ruang bebas, item baru adalah penyeimbang yang diperlukan untuk menjaga ketiga kotak tengah tetap di tengah secara horizontal. Item baru harus sama lebar dengan item D yang ada, atau kotak tengah tidak akan tepat di tengah.
Item baru dihapus dari tampilan dengan visibility: hidden
.
Pendeknya:
- Buat duplikat
D
elemen.
- Tempatkan di awal daftar.
- Gunakan
auto
margin fleksibel untuk menjaga A
, B
dan tetap di C
tengah, dengan kedua D
elemen menciptakan keseimbangan yang sama dari kedua ujungnya.
- Berlaku
visibility: hidden
untuk duplikatD
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>
Metode # 3: Margin Otomatis Flex & Item Flex Tak Terlihat (elemen semu)
Metode ini mirip dengan # 2, kecuali lebih bersih secara semantik dan lebar D
harus diketahui.
- Buat elemen pseudo dengan lebar yang sama dengan
D
.
- Tempatkan di awal wadah dengan
::before
.
- Gunakan
auto
margin fleksibel untuk menjaga A
, B
dan C
berpusat sempurna, dengan pseudo dan D
elemen menciptakan keseimbangan yang sama dari kedua ujungnya.
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>
Metode # 4: Tambahkan flex: 1
ke item kiri dan kanan
Dimulai dengan Metode # 2 atau # 3 di atas, alih-alih mengkhawatirkan lebar yang sama untuk item kiri dan kanan untuk mempertahankan keseimbangan yang sama, berikan saja masing-masing flex: 1
. Ini akan memaksa mereka berdua untuk mengkonsumsi ruang yang tersedia, sehingga memusatkan item tengah.
Anda kemudian dapat menambahkan display: flex
ke masing-masing item untuk menyelaraskan konten mereka.
CATATAN tentang menggunakan metode ini dengan min-height
: Saat ini di Chrome, Firefox, Edge dan mungkin browser lainnya, aturan singkatflex: 1
dirinci sebagai berikut:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Bahwa persentase Unit (%) pada flex-basis
penyebab metode ini untuk istirahat ketika min-height
digunakan pada wadah. Ini karena, sebagai aturan umum, persentase ketinggian pada anak-anak memerlukan height
pengaturan properti eksplisit pada orang tua.
Ini adalah aturan CSS lama sejak 1998 ( CSS Level 2 ) yang masih berlaku di banyak browser hingga tingkat tertentu. Untuk detail selengkapnya, lihat di sini dan di sini .
Berikut ilustrasi masalah yang diposting di komentar oleh 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>
Solusinya adalah tidak menggunakan unit persentase. Cobalah px
atau tidak sama sekali ( yang merupakan apa yang sebenarnya direkomendasikan oleh spec , terlepas dari kenyataan bahwa setidaknya beberapa browser utama telah menambahkan unit persentase untuk alasan apa pun).
#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>
Metode # 5: Layout Kotak CSS
Ini mungkin metode yang paling bersih dan paling efisien. Tidak perlu pemosisian absolut, elemen palsu, atau peretasan lainnya.
Cukup buat kisi dengan banyak kolom. Kemudian posisikan item Anda di kolom tengah dan akhir. Pada dasarnya, biarkan kolom pertama kosong.
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>