Pusat dan kanan luruskan elemen flexbox


147

Saya ingin memiliki A Bdan Cmenyelaraskan di tengah.

Bagaimana saya bisa Dpergi sepenuhnya ke kanan?

SEBELUM:

masukkan deskripsi gambar di sini

SETELAH:

masukkan deskripsi gambar di sini

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>

https://jsfiddle.net/z44p7bsx/

Jawaban:


214

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: relativeke wadah fleksibel.

Berlaku position: absoluteuntuk 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 topdan rightuntuk memindahkan elemen ini ke posisi.

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 automargin 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 Delemen.
  • Tempatkan di awal daftar.
  • Gunakan automargin fleksibel untuk menjaga A, Bdan tetap di Ctengah, dengan kedua Delemen menciptakan keseimbangan yang sama dari kedua ujungnya.
  • Berlaku visibility: hiddenuntuk duplikatD


Metode # 3: Margin Otomatis Flex & Item Flex Tak Terlihat (elemen semu)

Metode ini mirip dengan # 2, kecuali lebih bersih secara semantik dan lebar Dharus diketahui.

  • Buat elemen pseudo dengan lebar yang sama dengan D.
  • Tempatkan di awal wadah dengan ::before.
  • Gunakan automargin fleksibel untuk menjaga A, Bdan Cberpusat sempurna, dengan pseudo dan Delemen menciptakan keseimbangan yang sama dari kedua ujungnya.


Metode # 4: Tambahkan flex: 1ke 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: flexke 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: 1dirinci sebagai berikut:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

Bahwa persentase Unit (%) pada flex-basispenyebab metode ini untuk istirahat ketika min-heightdigunakan pada wadah. Ini karena, sebagai aturan umum, persentase ketinggian pada anak-anak memerlukan heightpengaturan 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 :

Solusinya adalah tidak menggunakan unit persentase. Cobalah pxatau 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).


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>


1
Bagus sekali, terima kasih atas penjelasannya! Saya kira potongan kode yang baru ditambahkan akan mendapat manfaat dari memperpendek teks contoh karena sebenarnya tidak jelas dari output bahwa konten terpusat / tidak terpusat karena viewport kecil. Hanya saya?
user2651804

"Item baru harus sama lebar dengan item D yang ada, atau kotak tengah tidak akan tepat di tengah." - itu menyebalkan bahwa itu harus memiliki lebar yang sama, tetapi terima kasih Tuhan untuk grid CSS :)
Vucko

Menggunakan teknik Grid, item tidak ada di dead center, apakah ada cara untuk membuat elemen logo mati di tengah? imgur.com/a/SVg9xsj
J86

Tidak cukup terbiasa dengan solusi grid meskipun berfungsi seperti pesona dan terbersih. Satu pertanyaan yang saya miliki adalah bagaimana memberi lebih banyak ruang ke kolom tengah tidak sama dengan ketiga?
Saba Ahang

5

Cara paling mudah

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>


2

Jika Anda ingin membuatnya sejajar, Anda cukup memasang rentang kosong dan membagi tiga rentang anak ke dalamnya.


2
dapatkah Anda memberikan demo singkat untuk mencadangkan pernyataan Anda?
klewis

2

Solusi paling sederhana adalah dengan membenarkan pusat konten ke wadah induk dan memberikan margin-kiri otomatis ke elemen anak pertama dan terakhir.

ul {
  display:flex;
  justify-content:center;
}


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>


1

Dengan menggunakan display:gridpendekatan ini, Anda bisa memasukkan semua ulanak ke dalam sel yang sama dan kemudian mengatur justify-self:

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>


0

Pertanyaan yang sangat jelas. Saya tidak bisa tidak memposting jawaban setelah beberapa jam menggali. Kita dapat memecahkan ini dengan tabel, sel-tabel, posisi absolut, mentransformasikan tetapi kita harus melakukannya dengan flexbox :)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd


8
Ini tidak benar-benar memusatkan item tengah karena hanya faktor dalam ruang yang tersisa , bukan seluruh ruang. codepen.io/anon/pen/QKGrRk
Michael Benjamin

@Michael_B, hak Anda tidak memperhatikan itu, saya salah. Kembali menggunakan posisi absolut :( Mungkin dengan perwakilan tinggi Anda, Anda harus menetapkan hadiah agar ini teratasi untuk selamanya. Saya akan tetapi saya memiliki perwakilan yang sangat rendah, bahkan lebih rendah sekarang mencoba membantu Anda.
rgfx

Tidak ada hadiah yang akan menambahkan perilaku baru ke model flexbox, oleh, oleh Michael_B, jawaban yang diberikan sama baiknya dengan yang didapat ... hari ini.
Ason

0

Aku diperluas pada Michael_B 's jawabannya

.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>

Di sini dengan bantuan SASS sebagai codepen


0

Terinspirasi oleh Metode # 5: Layout Grid CSS dari solusi @Michal Benjamin dan karena saya menggunakan Tailwind dan sampai sekarang masih tidak memiliki akses ke semua opsi grid secara default. Ini sepertinya berhasil:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS: Tidak yakin apakah mencampur flex dan grid seperti ini adalah ide yang bagus!


1
Anda tidak mencampur kisi dan flex, justifty-content adalah properti grid CSS DAN properti flexbox (sama untuk align-self)
Temani Afif

-1

Jawaban yang diterima dapat diubah sedikit karena Anda dapat menggunakan area templat kotak dan melakukannya tanpa elemen palsu

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr

-1
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;
  position:absolute;
  right:10px;

}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.