Lebar cairan dengan DIV dengan spasi yang sama

329

Saya memiliki DIV wadah cairan lebar.

Dalam hal ini saya memiliki 4 DIVs semua 300px x 250px ...

<div id="container">
   <div class="box1"> </div>
   <div class="box2"> </div>
   <div class="box3"> </div>
   <div class="box4"> </div>
</div>

Apa yang saya ingin terjadi adalah kotak 1 untuk melayang ke kiri, kotak 4 untuk melayang ke kanan dan kotak 2 dan 3 untuk ditempatkan secara merata di antara mereka. Saya ingin spasi menjadi lancar juga sehingga browser dibuat lebih kecil, ruang menjadi lebih kecil juga.

masukkan deskripsi gambar di sini

Lee Price
sumber
2
Mengapa tidak melakukan display:inline-block;alih - alih mengapung?
ayyp
1
karena IE6 / IE7 hanya mendukung inline-blockpada inlineelemen
Lee Harga
Oke, tidak yakin browser yang Anda tuju.
ayyp
1
Solusi terdekat yang bisa saya pikirkan adalah untuk membungkus setiap anak. Kotak div di div lain yang lebar 25%. Lalu, pusatkan anak .box div ke pembungkus. Div kotak. Akan ditempatkan secara merata, tetapi div kiri dan kanan tidak akan tepat ke tepi.
Paul Sham
5
Saya membuat ide @Paul Sham menjadi JSFiddle .
Sparky

Jawaban:

440

Lihat: http://jsfiddle.net/thirtydot/EDp8R/

  • Ini bekerja di IE6 + dan semua browser modern!
  • Saya telah membagi dua dimensi yang Anda minta hanya untuk membuatnya lebih mudah untuk dikerjakan.
  • text-align: justifydikombinasikan dengan .stretchapa yang menangani penentuan posisi.
  • display:inline-block; *display:inline; zoom:1perbaikan inline-blockuntuk IE6 / 7, lihat di sini .
  • font-size: 0; line-height: 0 memperbaiki masalah kecil di IE6.

#container {
  border: 2px dashed #444;
  height: 125px;
  text-align: justify;
  -ms-text-justify: distribute-all-lines;
  text-justify: distribute-all-lines;
  /* just for demo */
  min-width: 612px;
}

.box1,
.box2,
.box3,
.box4 {
  width: 150px;
  height: 125px;
  vertical-align: top;
  display: inline-block;
  *display: inline;
  zoom: 1
}

.stretch {
  width: 100%;
  display: inline-block;
  font-size: 0;
  line-height: 0
}

.box1,
.box3 {
  background: #ccc
}

.box2,
.box4 {
  background: #0ff
}
<div id="container">
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="box3"></div>
  <div class="box4"></div>
  <span class="stretch"></span>
</div>

Ekstra span( .stretch) dapat diganti dengan :after.

Ini masih berfungsi di semua browser yang sama dengan solusi di atas. :aftertidak bekerja di IE6 / 7, tapi mereka distribute-all-linestetap menggunakannya , jadi tidak masalah.

Lihat: http://jsfiddle.net/thirtydot/EDp8R/3/

Ada sedikit kelemahan :after: untuk membuat baris terakhir berfungsi sempurna di Safari, Anda harus berhati-hati dengan spasi putih di HTML.

Secara khusus, ini tidak berfungsi:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div>
</div>

Dan ini memang:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div></div>

Anda dapat menggunakan ini untuk jumlah anak sewenang-wenang divtanpa menambahkan boxNkelas untuk masing-masing dengan mengubah

.box1, .box2, .box3, .box4 { ...

untuk

#container > div { ...

Ini memilih setiap div yang merupakan anak pertama dari #containerdiv, dan tidak ada yang lain di bawahnya. Untuk menggeneralisasi warna latar belakang, Anda dapat menggunakan pemilih urutan ke-CSS3 , meskipun hanya didukung di IE9 + dan peramban modern lainnya:

.box1, .box3 { ...

menjadi:

#container > div:nth-child(odd) { ...

Lihat di sini untuk contoh jsfiddle.

tigapuluh
sumber
123
Saya membawa saya 3 jam untuk menemukan bahwa Anda harus memiliki spasi di antara setiap kotak di html. "Justify" memperluas ruang antara elemen dan jika konten Anda <div/><div/><div/>tidak berfungsi. Anda harus punya <div/> <div/> <div/>.
Venimus
5
hanya ingin mencatat itu :) karena sulit untuk dicatat jika Anda bekerja dengan konten yang dihasilkan (yang merupakan kasus umum). Saya berpikir untuk menggunakan justifyuntuk kasus seperti itu, tetapi terima kasih telah memberikan solusi yang berfungsi. menyelamatkan saya banyak percobaan (meskipun debugging 3 jam: D). Selain itu, saya dapat menambahkan catatan bahwa jika Anda ingin baris terakhir dibiarkan selaras, Anda harus menambahkan beberapa kotak tambahan (untuk melengkapi baris)
venimus
4
@venimus: Saya sudah menulis jawaban lain menggunakan teknik ini: stackoverflow.com/questions/10548417/… . Apa yang Anda lakukan untuk menghilangkan ketinggian ekstra yang disebabkan oleh penambahan kotak yang tidak terlihat?
tigapuluh
11
Dapatkah seseorang menjelaskan mengapa .stretch diperlukan?
atp
6
@ HartleySan: .stretch/ :afterdiperlukan karena (biasanya) dengan teks yang dibenarkan, baris terakhir tidak dibenarkan . Di sini, kami ingin baris terakhir dibenarkan, karena itu perlu :after. Adapun pertanyaan kedua Anda, saya telah menjelajahi beberapa waktu yang lalu di jawaban sebelumnya . Dalam jawaban itu, dibutuhkan JavaScript. Jika Anda perlu mendukung browser yang lebih lama (IE8) maka saya yakin Anda memang membutuhkan JavaScript.
tigapuluh
140

Cara termudah untuk melakukan ini sekarang adalah dengan flexbox:

http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Maka CSS secara sederhana:

#container {
    display: flex;
    justify-content: space-between;
}

demo: http://jsfiddle.net/QPrk3/

Namun , ini saat ini hanya didukung oleh browser yang relatif baru ( http://caniuse.com/flexbox ). Selain itu, spesifikasi tata letak flexbox telah berubah beberapa kali, jadi mungkin untuk mencakup lebih banyak browser dengan menambahkan sintaksis lama:

http://css-tricks.com/old-flexbox-and-new-flexbox/

http://css-tricks.com/using-flexbox/

Ben Jackson
sumber
1
Terima kasih untuk ini, sangat mudah, saya menerapkannya pada empat daftar spasi bahkan dalam catatan kaki tetap di bagian bawah halaman. Bekerja suguhan di FF28.0, Chrome 34.0.1847.116 m dan IE11.
user1063287
1
Flexbox bukanlah alat yang paling didukung di web dan tidak mengalahkan pendekatan klasik margin dan padding.
TheBlackBenzKid
Untuk semua orang yang mencari justifikasi beberapa div dengan lebar yang tidak ditentukan: gunakan flex-wrap with display: flex option. Ini akan membungkus div dengan lebar dinamis.
Kamil Budziewski
20

Jika css3 adalah opsi, ini dapat dilakukan dengan menggunakan calc()fungsi css .

Kasus 1: Membenarkan kotak pada satu baris ( FIDDLE )

Markup sederhana - sekelompok divs dengan beberapa elemen wadah.

CSS terlihat seperti ini:

div
{
    height: 100px;
    float: left;
    background:pink;
    width: 50px;
    margin-right: calc((100% - 300px) / 5 - 1px); 
}
div:last-child
{
    margin-right:0;
}

di mana -1px untuk memperbaiki bug IE9 + calc / rounding - lihat di sini

Kasus 2: Membenarkan kotak pada banyak baris ( FIDDLE )

Di sini, di samping calc()fungsi, media queriesdiperlukan.

Gagasan dasarnya adalah menyiapkan kueri media untuk setiap status # kolom, di mana saya kemudian menggunakan calc () untuk menghitung margin-kanan pada setiap elemen (kecuali yang ada di kolom terakhir).

Ini kedengarannya seperti banyak pekerjaan, tetapi jika Anda menggunakan KURANG atau SASS ini bisa dilakukan dengan mudah

(Ini masih bisa dilakukan dengan css reguler, tetapi kemudian Anda harus melakukan semua perhitungan secara manual, dan kemudian jika Anda mengubah lebar kotak Anda - Anda harus mengerjakan semuanya lagi)

Di bawah ini adalah contoh menggunakan KURANG: (Anda dapat menyalin / menempelkan kode ini di sini untuk bermain dengannya, [itu juga kode yang saya gunakan untuk menghasilkan biola yang disebutkan di atas])

@min-margin: 15px;
@div-width: 150px;

@3divs: (@div-width * 3);
@4divs: (@div-width * 4);
@5divs: (@div-width * 5);
@6divs: (@div-width * 6);
@7divs: (@div-width * 7);

@3divs-width: (@3divs + @min-margin * 2);
@4divs-width: (@4divs + @min-margin * 3);
@5divs-width: (@5divs + @min-margin * 4);
@6divs-width: (@6divs + @min-margin * 5);
@7divs-width: (@7divs + @min-margin * 6);


*{margin:0;padding:0;}

.container
{
    overflow: auto;
    display: block;
    min-width: @3divs-width;
}
.container > div
{
    margin-bottom: 20px;
    width: @div-width;
    height: 100px;
    background: blue;
    float:left;
    color: #fff;
    text-align: center;
}

@media (max-width: @3divs-width) {
    .container > div {  
        margin-right: @min-margin;
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @3divs-width) and (max-width: @4divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{3divs})/2 - 1px)";
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @4divs-width) and (max-width: @5divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{4divs})/3 - 1px)";
    }
    .container > div:nth-child(4n) {  
        margin-right: 0;
    }
}

@media (min-width: @5divs-width) and (max-width: @6divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{5divs})/4 - 1px)";
    }
    .container > div:nth-child(5n) {  
        margin-right: 0;
    }
}

@media (min-width: @6divs-width){
    .container > div {  
        margin-right: ~"calc((100% - @{6divs})/5 - 1px)";
    }
    .container > div:nth-child(6n) {  
        margin-right: 0;
    }
}

Jadi pada dasarnya Anda pertama-tama harus memutuskan lebar kotak dan margin minimum yang Anda inginkan di antara kotak-kotak tersebut.

Dengan itu, Anda dapat menentukan berapa banyak ruang yang Anda butuhkan untuk setiap negara bagian.

Kemudian, gunakan calc () untuk menghitung margin kanan, dan n-child untuk menghapus margin kanan dari kotak di kolom terakhir.

The keuntungan dari jawaban ini lebih jawaban yang diterima yang menggunakantext-align:justify adalah bahwa ketika Anda memiliki lebih dari satu baris dari kotak - kotak pada baris akhir tidak mendapatkan 'dibenarkan' misalnya: Jika ada 2 kotak yang tersisa di baris akhir - I tidak ingin kotak pertama berada di sebelah kiri dan yang berikutnya berada di sebelah kanan - tetapi kotak-kotak itu saling mengikuti secara berurutan.

Mengenai dukungan browser : Ini akan berfungsi pada IE9 +, Firefox, Chrome, Safari6.0 + - (lihat di sini untuk detail lebih lanjut) Namun saya perhatikan bahwa pada IE9 + ada sedikit kesalahan antara status kueri media. [jika ada yang tahu bagaimana cara memperbaikinya, saya benar-benar ingin tahu :)] <- TETAP DI SINI

Danield
sumber
13

Posting lain menyebutkan flexbox , tetapi jika lebih dari satu baris item diperlukan , space-betweenproperti flexbox gagal (lihat akhir posting)

Sampai saat ini, satu - satunya solusi bersih untuk ini adalah dengan

Modul Tata Letak Kotak CSS ( demo Codepen )

Pada dasarnya diperlukan kode yang relevan sampai saat ini:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fit, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: space-between; /* (4) */
  align-content: flex-start; /* (5) */
}

1) Jadikan elemen wadah sebagai wadah kotak

2) Atur grid dengan jumlah kolom 'otomatis' - sebagaimana diperlukan. Ini dilakukan untuk tata letak yang responsif. Lebar masing-masing kolom adalah 120px. (Perhatikan penggunaan auto-fit(seperti yang ditunjukkan auto-fill) yang (untuk tata letak 1-baris) runtuh trek kosong ke 0 - memungkinkan item untuk memperluas untuk mengambil ruang yang tersisa. (Lihat demo ini untuk melihat apa yang saya bicarakan )).

3) Atur celah / talang untuk baris dan kolom kisi - di sini, karena ingin tata letak 'ruang-di antara' - jarak sebenarnya akan menjadi jarak minimum karena akan tumbuh sesuai kebutuhan.

4) dan 5) - Mirip dengan flexbox.

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  grid-gap: 1rem;
  justify-content: space-between;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Demo codepen (Ubah ukuran untuk melihat efeknya)


Dukungan Browser - Caniuse

Saat ini didukung oleh Chrome (Blink), Firefox, Safari dan Edge! ... dengan dukungan parsial dari IE (Lihat posting ini oleh Rachel Andrew)


NB:

space-betweenProperti Flexbox berfungsi dengan baik untuk satu baris item, tetapi ketika diterapkan pada wadah fleksibel yang membungkus itemnya - (dengan flex-wrap: wrap) - gagal, karena Anda tidak memiliki kendali atas penyelarasan baris terakhir item; baris terakhir akan selalu dibenarkan (biasanya bukan yang Anda inginkan)

Untuk menunjukkan:

Codepen (Ubah ukuran untuk melihat apa yang saya bicarakan)


Bacaan lebih lanjut tentang kisi-kisi CSS:

Danield
sumber
1
Jawaban yang sangat diremehkan. Ini adalah cara paling sederhana dan paling efektif untuk mencapai apa yang ingin saya lakukan. Terima kasih.
Barnaby Mercer
1
Ini adalah jumlah terkecil CSS (dan tidak ada JS!) Yang menghasilkan perilaku persis seperti yang saya cari, dengan beberapa penyesuaian ukuran dan ruang.
EKW
1
Saya sudah mencari ini sebentar dan akhirnya menemukannya !. Terima kasih @Danield
nareeboy
2

Ini bekerja untuk saya dengan 5 gambar dalam ukuran yang berbeda.

  1. Buat div wadah
  2. Daftar tidak terurut untuk gambar
  3. Pada css yang tidak berorden harus ditampilkan secara vertikal dan tanpa peluru
  4. Benarkan konten dari wadah div

Ini berfungsi karena justify-content: space-between, dan ada di daftar, ditampilkan secara horizontal.

Tentang CSS

 #container {
            display: flex;
            justify-content: space-between;
 }
    #container ul li{ display:inline; list-style-type:none;
}

Di html

<div id="container"> 
  <ul>  
        <li><img src="box1.png"><li>
        <li><img src="box2.png"><li>
        <li><img src="box3.png"><li>
        <li><img src="box4.png"><li>
        <li><img src="box5.png"><li>
    </ul>
</div>
Sebastián Brun Valiente
sumber
Meskipun kode ini mungkin berfungsi, jawaban yang baik akan mencakup penjelasan tentang cara kerjanya dan mengapa itu merupakan solusi yang baik.
Blackwood
Perlu dicatat bahwa flexbox tidak (atau hanya sebagian) didukung oleh IE caniuse.com/#feat=flexbox
David Salamon
apakah ini responsif?
stackdave
1

di jQueryAnda mungkin menargetkan Induk langsung.

INI BERMANFAAT JIKA ANDA TIDAK MENGETAHUI BAGAIMANA CARA BANYAK ANAK AKAN DITAMBAH SECARA DINAMIS atau JIKA ANDA TIDAK BISA MENGETAHUI ANGKA MEREKA.

var tWidth=0;

$('.children').each(function(i,e){
tWidth += $(e).width();

///Example: If the Children have a padding-left of 10px;..
//You could do instead:
tWidth += ($(e).width()+10);

})
$('#parent').css('width',tWidth);

Ini akan membiarkan parenttumbuh secara horizontal saat childrenbeng ditambahkan.

CATATAN: Ini mengasumsikan bahwa '.children'have widthdan HeightSet

Semoga Itu Membantu.

ErickBest
sumber
1

Jika Anda tahu jumlah elemen per "baris" dan lebar wadah, Anda bisa menggunakan pemilih untuk menambahkan margin ke elemen yang Anda butuhkan agar tampak benar.

Saya memiliki deretan tiga div yang saya inginkan dibenarkan sehingga menggunakan:

.tile:nth-child(3n+2) { margin: 0 10px }

ini memungkinkan div tengah di setiap baris memiliki margin yang memaksa div ke-1 dan ke-3 ke tepi luar wadah

Juga bagus untuk hal-hal lain seperti warna latar perbatasan dll

Dave Robertson
sumber