Kotak-fleksibel: Sejajarkan baris terakhir ke kotak

379

Saya memiliki tata letak kotak fleksibel sederhana dengan wadah seperti:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Sekarang saya ingin item di baris terakhir disejajarkan dengan yang lain. justify-content: space-between;harus digunakan karena lebar dan tinggi kisi dapat disesuaikan.

Saat ini sepertinya

Item di kanan bawah harus di tengah

Di sini, saya ingin item di kanan bawah berada di "kolom tengah". Apa cara paling sederhana untuk mencapainya? Ini jsfiddle kecil yang menunjukkan perilaku ini.

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>

Thorben Croisé
sumber
Periksa solusi saya di sini, saya pikir ini bekerja dengan baik tanpa hack, hanya matematika: stackoverflow.com/questions/18744164/…
Sebastien Lorber
5
Atau, gunakan bisa menggunakan modul css grid yang lebih baru - yang tidak memiliki masalah ini
Danield
1
Saya menambahkan solusi JS generik untuk kasus-kasus ketika lebar anak adalah variabel, membuat jumlah item pada variabel baris juga.
tao

Jawaban:

417

Tambahkan ::afteryang mengisi ruang secara otomatis. Tidak perlu mencemari HTML Anda. Berikut ini adalah codepen yang menunjukkannya: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid::after {
  content: "";
  flex: auto;
}
Dan Andreasson
sumber
17
Mungkinkah membuatnya bekerja dengan ruang-sekitar entah bagaimana?
Tom
61
@DanAndreasson Ada dua masalah, itu tidak mulai dari kiri (seperti spasi-antara), dan juga ruang antara item dari baris terakhir berbeda dari pada baris sebelumnya (mensimulasikan beberapa item lebar tetap dalam "ukuran apa pun" kisi - berhubungan dengan keduanya) ... codepen.io/anon/pen/gPoYZE Yang saya inginkan adalah mempertahankan "strategi" (ruang-sekitar atau ruang-antara) tetapi mulai dari kiri seperti pada baris sebelumnya ... Saya ingin tahu, apakah mungkin untuk menggeneralisasi solusi luar biasa Anda.
Tom
44
Ini hanya berfungsi karena item memiliki padding untuk menempatkan mereka dan lebar persentase gabungan sama dengan 100% untuk setiap set 4. Dalam codepen ini saya dihapus justify-content: space-between;dari .griddan dihapus .grid:afterdan bekerja sama. Sekarang jika Anda mencoba sesuatu seperti ini benar-benar rusak. Perhatikan lebar untuk setiap set 4 jangan tambahkan hingga 100%. Dalam biola OP, lebar diatur dalam px sehingga solusi Anda tidak bekerja dalam situasi ini.
Jacob Alvarez
22
Mencoba solusi ini, pada awalnya, item yang pendek pada baris terakhir tidak menyebar dengan baik space-between. Namun, ketika saya mengatur flex-basisdari .grid:afterke ukuran yang sama seperti barang-barang lainnya di grid (per-breakpoint, override default / basis kode modul di atas), baris penyebaran terakhir dengan benar. Tampaknya berfungsi di Safari, iOS, Firefox, Chrome (perlu menguji IE) dan ukuran baris terbesar saya adalah 3 pada implementasi awal saya.
webbower
8
Untuk kebutuhan saya ini bekerja dengan modifikasi berikut: { content: "";flex: 0 0 32%;max-width: 480px;}dan saya mengubah max-width dengan perubahan permintaan media sehingga grid sempurna di semua lebar.
Colin Wiseman
160

Satu teknik akan memasukkan sejumlah elemen tambahan (sebanyak jumlah maksimum elemen yang Anda harapkan dalam satu baris) yang diberi tinggi nol. Ruang masih terbagi, tetapi baris-baris tak berguna runtuh:

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

Di masa depan, ini dapat dicapai dengan menggunakan banyak ::after(n).

dalgard
sumber
11
Sayangnya ini mencemari markup dengan cara yang tidak semantik, tetapi ini benar-benar berfungsi. : Saya berharap saya tahu cara lain untuk mereplikasi perilaku ini, flexbox atau lainnya, yang tidak memerlukan elemen non-semantik.
Ryan Norbauer
33
Setuju, ini kotor, tetapi berhasil, dan lebih sedikit retas daripada banyak peretasan. Hentikan itu, saya menggunakannya, sampai :: setelah (12) mendapatkan dukungan, atau mereka menambahkan beberapa opsi justifikasi tambahan. Sangat memalukan karena cara flexbox membenarkan bekerja saat ini benar-benar salah! Jika Anda membenarkan paragraf teks, Anda tidak akan pernah mencoba untuk membenarkan baris terakhir. Seharusnya menjadi pilihan, saya tidak percaya mereka melewatkan ini.
Codemonkey
4
Saya datang dengan satu-satunya solusi CSS .. peringatan itu hanya dapat menjelaskan dua item yang hilang, jadi hanya akan bekerja dengan aman dalam kotak fleksibel dengan maksimum tiga item per baris pembungkus. Demo: codepen.io/lukejacksonn/pen/dozqVq Prinsipnya di sini adalah menggunakan elemen pseudo sebagai anak - anak tambahan dan memberi mereka properti flex yang sama dengan item dalam wadah.
lukejacksonn
8
@Codemonkey Jesus. Saya baru saja mulai menggunakan flexbox untuk berpikir bagaimana saya akan menyingkirkan semua peretasan yang dimaksudkan untuk menyelaraskan blok-blok sebaris di dalam kotak, dan sekarang ternyata itu tidak mungkin! Saya telah mencapai blok itu segera, mencapai batas yang saya pikir saya hampir tidak akan pernah mencapai dengan senang hati menyelesaikan semua masalah CSS lama yang tidak terpecahkan ini. Kurasa tidak terlalu cepat. Hanya butuh 20 tahun untuk mendapatkan pemusatan vertikal yang benar - kita tentu bisa menunggu. Astaga, sepertinya tugasnya sangat sederhana ...
Andrey
3
@dalgard saya tidak berpikir begitu. Lihat komentar saya .
Jacob Alvarez
109

Seperti yang telah disebutkan oleh poster lain - tidak ada cara bersih untuk menyelaraskan kiri baris terakhir dengan flexbox (setidaknya sesuai dengan spesifikasi saat ini)

Namun, untuk apa nilainya: Dengan Modul Layout Kotak CSS ini sangat mudah untuk diproduksi:

Pada dasarnya kode yang relevan bermuara pada ini:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Jadikan elemen wadah sebagai wadah kotak

2) Atur grid dengan kolom otomatis dengan lebar 100px. (Perhatikan penggunaan pengisian-otomatis (seperti yang ditunjukkan auto-fit- yang (untuk tata letak 1-baris) runtuh trek kosong ke 0 - menyebabkan item memperluas untuk mengambil ruang yang tersisa. Ini akan menghasilkan 'ruang-antara 'tata letak ketika kotak hanya memiliki satu baris yang dalam kasus kami bukan yang kita inginkan (lihat demo ini untuk melihat perbedaan di antara mereka)).

3) Atur celah / talang untuk baris dan kolom kisi - di sini, karena menginginkan tata letak 'antar-ruang' - jarak sebenarnya akan menjadi jarak minimum karena akan tumbuh seperlunya.

4) Mirip dengan flexbox.

Demo Codepen (Ubah ukuran untuk melihat efeknya)

Danield
sumber
4
Solusi yang bagus. Satu-satunya masalah adalah tidak bekerja dengan IE10 / 11.
zendu
1
Mengenai auto-fit, ada bug di Chrome 57-60 (dan browser berdasarkan mesinnya, seperti Samsung Internet 6.0) karena speknya agak ambigu pada saat itu. Sekarang spek telah diklarifikasi dan versi baru Chrome ditampilkan auto-fitdengan benar, tetapi browser dengan mesin lama masih digunakan, jadi harap berhati-hati dengan nilai ini.
Ilya Streltsyn
4
Mengingat kemungkinan saat ini, ini sekarang harus menjadi jawaban yang diterima. Menggunakan :afterpseudo-elemen dapat menyebabkan hasil yang tidak diinginkan dalam kasus tepi.
Paul
2
@ Danield saran ini banyak membantu saya, terima kasih!
Krys
4
Ini harus menjadi jawaban yang diterima. Saya akan menggabungkannya dengan flexbox sebagai fallback, dalam semangat peningkatan progresif: browser yang tidak mendukung grid akan menampilkan versi flexbox, yang cukup dekat untuk saya.
Palantir
27

Tanpa markup tambahan, hanya menambahkan ::afterberfungsi untuk saya menentukan lebar kolom.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

Dengan HTML seperti ini:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>
Nicolás Arévalo
sumber
9
ini menarik, tetapi tidak sepenuhnya benar. masalahnya muncul ketika Anda berurusan dengan lebih dari dua elemen di baris bawah - jarak yang muncul di antara elemen di baris di atas tidak pernah muncul di yang terakhir; barang-barang yang dikemas bersama-sama, meniadakan utilitas asli ruang-antara.
John Haugeland
bahkan lebih baik jika Anda menggunakan flex-basis: 10embukan lebar.
beytarovski
14

Kamu tidak bisa Flexbox bukan sistem kisi. Itu tidak memiliki konstruksi bahasa untuk melakukan apa yang Anda minta, setidaknya tidak jika Anda menggunakan justify-content: space-between. Yang paling dekat dengan Flexbox adalah dengan menggunakan orientasi kolom, yang mengharuskan pengaturan tinggi eksplisit:

http://cssdeck.com/labs/pvsn6t4z (catatan: awalan tidak termasuk)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

Namun, akan lebih mudah untuk hanya menggunakan kolom, yang memiliki dukungan lebih baik dan tidak memerlukan pengaturan ketinggian tertentu:

http://cssdeck.com/labs/dwq3x6vr (catatan: awalan tidak termasuk)

ul {
  columns: 15em;
}
cimmanon
sumber
2
Ada jalan; lihat jawaban saya.
dalgard
@dalgard, jawaban Anda adalah solusi, bukan solusi yang benar. Jawaban cimmanon benar.
Jonah
1
@Jonah saya pikir "teknik" adalah deskripsi yang adil dari jawaban saya. Ini tentu saja berfungsi sebagai solusi bagi banyak orang, termasuk si penanya.
dalgard
2
@dalgard Itu tidak mengubah fakta bahwa Flexbox tidak menyediakan konstruksi bahasa untuk melakukan apa yang diminta. Selain itu, saya berpendapat bahwa menambahkan elemen palsu adalah praktik yang sangat kotor, tepat di sana dengan menggunakan tabel untuk tata letak.
cimmanon
4
Itu tidak cantik, tetapi pengembangan ujung depan adalah seni dari kemungkinan; pragmatisme adalah premis dasar. Saya pikir kata ini sangat salah tempat, karena elemen tambahan sedang digunakan untuk penataan pada 99,9% dari situs web dunia nyata (lih. Elemen wadah Bootstrap).
dalgard
12

Solusi yang mungkin adalah menggunakan justify-content: flex-start;pada .gridwadah, batasan ukuran pada anak-anaknya, dan margin pada elemen anak yang sesuai - tergantung pada jumlah kolom yang diinginkan.

Untuk kisi 3 kolom, CSS dasar akan terlihat seperti ini:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

Ini solusi lain yang tidak sempurna, tetapi berhasil.

http://codepen.io/tuxsudo/pen/VYERQJ

Jared
sumber
11

Saya tahu ada banyak jawaban di sini tapi .. Cara paling sederhana untuk melakukan ini adalah dengan gridalih - alih flexdan grid template columnsdengan repeatdan auto fills, di mana Anda harus mengatur jumlah piksel yang telah Anda berikan untuk setiap elemen, 100pxdari kode snippet Anda.

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>

Peselancar perak
sumber
2
Ini adalah solusi yang tepat untuk mendapatkan item baris terakhir tetap selaras.
a.barbieri
Saya setuju, cara yang tepat adalah menggunakan kisi. Dapat dicapai dengan flexbox tetapi jauh lebih bersih untuk menggunakan kisi.
nbarth
6

Iya.! Kita dapat tetapi dengan beberapa pertanyaan media & Jumlah kolom maksimum tidak ditentukan sebelumnya .

Di sini saya menggunakan 4 kolom. Periksa kode saya:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

CATATAN
1) Tidak perlu membuat div anak. Ini bisa berupa tag lain seperti 'img' r apa pun yang Anda inginkan ..
2) Jika Anda ingin lebih banyak kolom sesuaikan kueri media dan maksimum no.of kolom.

Mohamed Mohaideen AH
sumber
Ini hanya menghasilkan 3 dalam IE terbaru
Akxe
6

Jika Anda ingin kisi dengan beberapa ruang antara item dan item dimulai tanpa spasi awal maka solusi sederhana ini berfungsi:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

Jika Anda ingin ruang 5px awal maka cukup hapus margin negatif :) Sederhana.

https://jsfiddle.net/b97ewrno/2/

Jawaban yang diterima, sementara bagus, itu menyebabkan tidak ada ruang antara elemen di baris kedua ..

OZZIE
sumber
1
Terkejut ini tidak memiliki suara lagi. Ini adalah pendekatan indah yang termasuk dalam museum Flex.
Eduardo La Hoz Miranda
1
@EduardoLaHozMiranda terima kasih! Tapi mengapa "museum"? IE11 tidak mendukung css grid dan sebagian besar situs masih perlu mendukungnya. + Beberapa timer besar dalam pengembangan frontend masih mengklaim ada berbagai kasus penggunaan untuk grid vs flexbox. Tetapi mungkin Anda hanya bermaksud bahwa ini harus menjadi bagian penting dari sejarah web: D
OZZIE
1
Lol, ya. Saya senang saat itu. Hanya berarti itu bagus dan minimal mengambil masalah ini.
Eduardo La Hoz Miranda
@dencey Anda tidak perlu tahu bahwa untuk solusi ini, itu 25% jadi maks 4 per baris, tetapi Anda dapat menggunakan persen apa pun yang Anda inginkan
OZZIE
@ OZZIE Maksud saya lebar item tetap (seperti 100px), tetapi lebar kontainer dinamis, jadi item per baris dinamis.
dencey
4

Jika Anda ingin menyelaraskan item terakhir ke kisi, gunakan kode berikut:

Wadah kotak

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Item dalam kisi

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

Caranya adalah dengan mengatur lebar maksimum item sama dengan lebar maksimum dari .card-grid: after.

Demo langsung di Codepen

Frank Spin
sumber
cthulu memberkati Anda dan komputer Anda
L422Y
3
Pendekatan ini tidak berfungsi ketika ukuran kartu diperbaiki dan jumlah kartu di setiap baris tidak diketahui. codepen.io/zendu/pen/WXNGvo
zendu
3

Dimungkinkan untuk menggunakan "mulai-fleksibel" dan untuk menambahkan margin secara manual. Ini membutuhkan beberapa peretasan matematika tetapi jelas mudah dilakukan dan membuatnya mudah digunakan dengan preprocessor CSS seperti KURANG.

Lihat misalnya mixin KURANG ini:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

Dan kemudian dapat dengan mudah digunakan untuk menampilkan tata letak grid responsif:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Ini adalah contoh dari

http://codepen.io/anon/pen/YyLqVB?editors=110

Sebastien Lorber
sumber
Anda tidak pernah menggunakan @contentPercent. Apakah Anda berniat melakukannya?
neverfox
lebar: @ contentPercent / @ columnNumber;
realtebo
WOW ! Saya sangat terkesan dengan solusi ini. Saya akan mencoba beradaptasi dengan situasi saya
realtebo
3

Masalah ini diselesaikan untuk saya menggunakan kotak CSS,

Solusi ini hanya berlaku jika Anda memiliki jumlah kolom tetap yaitu tidak. elemen untuk ditampilkan dalam satu baris

-> menggunakan kisi tetapi tidak menentukan jumlah baris, karena jumlah elemen meningkatkannya membungkus ke dalam kolom dan menambahkan baris secara dinamis, saya telah menentukan tiga kolom dalam contoh ini

-> Anda tidak harus memberikan posisi apa pun kepada anak / sel Anda, karena itu akan memperbaikinya, yang tidak kami inginkan.

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}

Ashwin
sumber
1

Versi ini adalah cara terbaik untuk blok dengan lebar tetap:

http://codepen.io/7iomka/pen/oxxeNE

Dalam kasus lain - versi dalgard

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
justify-content:center;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  max-width:200px;
  min-width:200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

Znacovean Simion
sumber
0

Ada cara tanpa flexbox, meskipun Anda harus memenuhi ketentuan berikut. 1) Wadah memiliki bantalan. 2) Item berukuran sama dan Anda tahu persis berapa banyak yang Anda inginkan per baris.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

Padding yang lebih kecil di sisi kanan wadah memungkinkan untuk padding tambahan di sebelah kanan setiap item daftar. Dengan asumsi item lain dalam induk yang sama dengan objek daftar diisi dengan 0 5%, itu akan rata dengan mereka. Anda juga dapat menyesuaikan persentase dengan seberapa banyak margin yang Anda inginkan atau menggunakan menghitung nilai px.

Tentu saja, Anda dapat melakukan hal yang sama tanpa bantalan pada wadah dengan menggunakan nth-child (IE 9+) untuk menghilangkan margin pada setiap kotak ketiga.

ansorensen
sumber
0

Menggunakan flexbox dan beberapa pertanyaan media, saya membuat ini sedikit bekerja: http://codepen.io/una/pen/yNEGjv (ini sedikit hacky tetapi berfungsi):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}
Una Kravets
sumber
0

Saya membuat mixin SCSS untuk itu.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

Ini adalah tautan codepen: http://codepen.io/diana_aceves/pen/KVGNZg

Anda hanya perlu mengatur lebar item dalam persentase dan jumlah kolom.

Saya harap ini dapat membantu Anda.

Diana
sumber
0

Berikut beberapa mixins scss lainnya.

Mixin ini berasumsi bahwa Anda tidak akan menggunakan plugin js seperti Isotop (mereka tidak menghormati urutan markah html, sehingga mengacaukan aturan css n).

Selain itu, Anda akan dapat mengambil keuntungan penuh dari mereka terutama jika Anda menulis breakpoint responsif Anda dengan mobile terlebih dahulu. Anda idealnya akan menggunakan flexbox_grid () pada breakpoint yang lebih kecil dan flexbox_cell () pada breakpoints berikut. flexbox_cell () akan mengatur ulang margin yang sebelumnya tidak lagi digunakan pada breakpoint yang lebih besar.

Dan omong-omong, selama Anda benar mengatur properti fleksibel penampung Anda, Anda juga dapat menggunakan hanya flexbox_cell () pada item, jika perlu.

Berikut kodenya:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Pemakaian:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Jelas, itu terserah Anda untuk akhirnya mengatur padding / margin / width dari kontener dan margin bawah sel dan sejenisnya.

Semoga ini bisa membantu!

Luca Reghellin
sumber
0

Ini cukup hacky, tetapi berhasil untuk saya. Saya berusaha mencapai jarak / margin yang konsisten.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/

RustyDev
sumber
0

Sepertinya tidak ada yang mengusulkan solusi flex-grow pada item terakhir. Idenya adalah untuk memiliki item flex terakhir Anda untuk mengambil semua tempat itu dapat menggunakan flex-grow: 1.

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid > *:last-child {
  flex-grow: 1;
}

Catatan: Solusi ini tidak sempurna, terutama jika Anda telah memusatkan elemen di dalam item flex Anda karena akan berpusat pada item flex terakhir yang mungkin besar.

Dionys
sumber
0

Ini adalah kombinasi dari banyak jawaban tetapi tidak persis apa yang saya butuhkan - yaitu, menyelaraskan anak terakhir dalam wadah fleksibel ke kiri sambil mempertahankan ruang-antara perilaku (dalam hal ini adalah tiga kolom tata letak).

Inilah markupnya:

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
}

.flex-container:after {
  content: "";
  flex-basis: 30%;
}
Margaret
sumber
1
Agar lebih generik: ukuran dasar-lentur harus sama dengan ukuran anak-anaknya.
Christian Toffolo
1
Saya menemukan flex-grow: 0.9alih-alih flex-basiskarya untuk sejumlah kolom. Diuji dalam banyak browser modern - itu berfungsi di dalamnya semua kecuali paddingnya rusak di IE (tetapi bekerja di Edge0
Patabugen
0

Asumsi:

  • Anda ingin tata letak kotak 4 kolom dengan pembungkus
  • Jumlah item belum tentu kelipatan 4

Tetapkan margin kiri pada setiap item kecuali item 1, 5 dan 9 dan seterusnya. Jika margin kiri adalah 10px maka setiap baris akan memiliki margin 30px didistribusikan di antara 4 item. Lebar persentase untuk item dihitung sebagai berikut:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Ini adalah solusi yang layak untuk masalah yang melibatkan baris terakhir dari flexbox.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0 3em;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>

Salman A
sumber
0

Jika Anda tahu lebar spasi antara elemen dalam baris dan jumlah elemen dalam satu baris, ini akan berhasil:

Contoh: 3 elemen berturut-turut, celah 10px antara elemen

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}
tidak juga
sumber
0

Cukup Gunakan Trik Jquery / Javascript untuk menambahkan div kosong:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}
Waheed Mazhar
sumber
-1

Oh boy, saya pikir saya menemukan solusi yang baik dengan CSS minimal dan tanpa JS. Coba lihat:

img {width:100%;}
li {
  display: inline-block;
  width:8em;
  list-style:none;
}
ul {text-align: justify;}
<ul>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Kuncinya di sini adalah untuk mengingat bahwa apa yang kita coba capai adalah persis apa text-align: justifyyang berhasil!

Elemen-elemen kosong di HTML ada untuk membuat tampilan baris terakhir sempurna tanpa mengubah tampilan, tetapi mungkin tidak diperlukan mengingat apa yang Anda coba capai. Untuk keseimbangan sempurna dalam setiap situasi, Anda memerlukan setidaknya x-4 elemen kosong, x menjadi jumlah elemen untuk ditampilkan, atau n-2, n menjadi jumlah kolom yang ingin Anda tampilkan.

Sharcoux
sumber
-1

Cukup tambahkan beberapa item palsu dengan properti yang sama kecuali ketinggian ditetapkan ke 0px sampai akhir.

Erik Parso
sumber
Menambahkan barang palsu adalah praktik buruk dalam segala hal. Anda tidak seharusnya mengisi DOM dengan barang-barang hanya untuk meretas css kecuali wajib. Karena berbagai alasan, mulai dari aksesibilitas, membanjiri basis kode dengan hal-hal aneh, hingga membuat logika lebih kompleks untuk dipahami dan daftarnya terus berlanjut. Jangan rekomendasikan peretasan kecuali Anda secara eksplisit mengatakan itu mungkin solusi yang buruk atau ada kasus khusus untuk itu.
Eksapsy
-4

Anda ingin menyelaraskan

gunakan align-content: flex-start;sebagai gantijustify-content: space-between;

ini menarik item baris terakhir ke kiri, dan juga mendistribusikan ruang secara merata,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


solusi danAnderson BUKAN DINAMIS. PERIODE !!

ketika lebar item berubah dari 25 menjadi 28 dan anderson gagal ruang di antara gambar

danAnderson: https://codepen.io/anon/pen/ZwYPmB?editors=1100

dinamis: https://codepen.io/anon/pen/aQggBW?editors=1100

Itulah yang saya coba katakan. dans adalah peretasan .....

bh_earth0
sumber
-7

Saya bisa melakukannya dengan justify-content: space-betweendi atas wadah

kenyal
sumber