ความกว้างของของไหลที่มี DIV เว้นระยะเท่ากัน


329

ฉันมีภาชนะบรรจุความกว้างของของเหลว DIV

ภายในนี้ฉันมี 4 DIVs ทั้งหมด 300px x 250px ...

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

สิ่งที่ฉันต้องการจะเกิดขึ้นก็คือกล่องที่ 1 ที่จะลอยไปทางซ้ายกล่องที่ 4 จะลอยไปทางขวาและช่องที่ 2 และ 3 ที่จะเว้นระยะระหว่างพวกเขาอย่างเท่าเทียมกัน ฉันต้องการให้การเว้นวรรคนั้นราบรื่นเช่นกันดังนั้นเบราว์เซอร์ก็ยิ่งเล็กลงพื้นที่ก็เล็กลงเช่นกัน

ป้อนคำอธิบายรูปภาพที่นี่


2
ทำไมไม่ทำdisplay:inline-block;แทนที่จะเป็นแบบลอยตัว?
ayyp

1
เพราะ IE6 / IE7 สนับสนุนเฉพาะinline-blockในinlineองค์ประกอบ
ลีราคา

ตกลงไม่แน่ใจว่าคุณต้องการเบราว์เซอร์ใด
ayyp

1
วิธีแก้ปัญหาที่ใกล้เคียงที่สุดที่ฉันคิดได้คือการห่อเด็กแต่ละคนให้กับ. div ในอีกอันที่มีความกว้าง 25% จากนั้นจัดกึ่งกลางเด็ก. กล่อง div ไปที่ wrapper div. box จะเว้นระยะเท่ากัน แต่ div ด้านซ้ายและขวาจะไม่อยู่ชิดขอบ
พอลแชม

5
ฉันทำคิด @ Paul Sham เป็นที่JSFiddle
ปาร์

คำตอบ:


440

ดู: http://jsfiddle.net/thirtydot/EDp8R/

  • ใช้งานได้ในIE6 + และเบราว์เซอร์สมัยใหม่ทั้งหมด!
  • ฉันแบ่งส่วนข้อมูลตามที่คุณขอลดลงครึ่งหนึ่งเพื่อให้ทำงานง่ายขึ้น
  • text-align: justifyรวมกับ.stretchสิ่งที่จัดการตำแหน่ง
  • display:inline-block; *display:inline; zoom:1แก้ไขinline-blockสำหรับ IE6 / 7, ดูที่นี่
  • font-size: 0; line-height: 0 แก้ไขปัญหาเล็กน้อยใน 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>

พิเศษspan( .stretch) :afterสามารถถูกแทนที่ด้วย

สิ่งนี้ยังคงใช้งานได้ในเบราว์เซอร์เดียวกับโซลูชันข้างต้น :afterไม่ทำงานใน IE6 / 7 แต่พวกเขากำลังใช้distribute-all-linesอยู่ดังนั้นมันจึงไม่สำคัญ

ดู: http://jsfiddle.net/thirtydot/EDp8R/3/

มีข้อเสียเล็กน้อย:afterคือ: เพื่อให้แถวสุดท้ายทำงานได้อย่างสมบูรณ์ใน Safari คุณต้องระวังช่องว่างใน HTML

สิ่งนี้ไม่ได้ผล:

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

และสิ่งนี้จะ:

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

คุณสามารถใช้สิ่งนี้กับจำนวนลูกใด ๆ โดยdivไม่ต้องเพิ่มboxNชั้นเรียนให้กับแต่ละคนโดยการเปลี่ยน

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

ถึง

#container > div { ...

นี่เป็นการเลือก div ใด ๆ ที่เป็นลูกคนแรกของ#containerdiv และไม่มีคนอื่นอยู่ด้านล่าง ในการทำให้สีพื้นหลังทั่วไปคุณสามารถใช้ตัวเลือกลำดับที่ 3 ของ CSS3แม้ว่าจะรองรับเฉพาะใน IE9 + และเบราว์เซอร์สมัยใหม่อื่น ๆ :

.box1, .box3 { ...

กลายเป็น:

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

ดูที่นี่สำหรับตัวอย่าง jsfiddle


123
ฉันใช้เวลา 3 ชม. เพื่อหาว่าคุณควรมีช่องว่างระหว่างแต่ละกล่องใน html "ปรับ" ขยายช่องว่างระหว่างองค์ประกอบและถ้าเนื้อหาของคุณ<div/><div/><div/>มันไม่ทำงาน <div/> <div/> <div/>คุณจำเป็นต้องมี
venimus

5
แค่ต้องการที่จะทราบว่า :) เพราะมันยากที่จะทราบว่าคุณทำงานกับเนื้อหาที่สร้างขึ้น (ซึ่งเป็นกรณีทั่วไป) ฉันคิดว่าจะใช้justifyสำหรับกรณีเช่นนี้ แต่ขอขอบคุณที่ให้วิธีแก้ปัญหาการทำงาน บันทึกการทดลองมากมาย (แม้จะมีการดีบัก 3h: D) นอกจากนี้ฉันสามารถเพิ่มบันทึกย่อได้ว่าหากคุณต้องการให้แถวสุดท้ายของคุณอยู่ในแนวเดียวกันคุณควรเพิ่มกล่องที่มองไม่เห็น (เพื่อทำให้แถวเสร็จ)
venimus

4
@venimus: ผมเคยเขียนคำตอบอื่นใช้เทคนิคนี้: stackoverflow.com/questions/10548417/... คุณทำอะไรเพื่อกำจัดความสูงพิเศษที่เกิดจากการเพิ่มกล่องที่มองไม่เห็น
สามสิบ

11
บางคนสามารถอธิบายได้ว่าทำไมต้องมี .stretch?
atp

6
@HartleySan ที่: .stretch/ :afterเป็นสิ่งจำเป็นเพราะ (ปกติ) ที่มีข้อความเป็นธรรมบรรทัดสุดท้ายไม่เป็นธรรม :afterที่นี่เราไม่ต้องการที่บรรทัดสุดท้ายเป็นธรรมจึงจำเป็นที่จะต้อง สำหรับคำถามที่สองของคุณผมสำรวจว่าในขณะที่ที่ผ่านมาในคำตอบก่อนหน้า ในคำตอบนั้นจำเป็นต้องใช้ JavaScript หากคุณต้องการรองรับเบราว์เซอร์รุ่นเก่า (IE8) ฉันเชื่อว่าคุณต้องใช้ JavaScript
สามสิบ

140

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือด้วย flexbox:

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

CSS นั้นเป็นเพียง:

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

ตัวอย่าง: http://jsfiddle.net/QPrk3/

อย่างไรก็ตามปัจจุบันนี้รองรับเฉพาะเบราว์เซอร์ที่ค่อนข้างล่าสุด ( http://caniuse.com/flexbox ) นอกจากนี้ข้อมูลจำเพาะสำหรับรูปแบบเฟล็กบ็อกซ์มีการเปลี่ยนแปลงสองสามครั้งดังนั้นจึงเป็นไปได้ที่จะครอบคลุมเบราว์เซอร์มากขึ้นโดยรวมถึงไวยากรณ์ที่เก่ากว่า:

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

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


1
ขอบคุณสำหรับสิ่งนี้ง่ายมากฉันใช้กับสี่รายการที่เว้นวรรคในส่วนท้ายคงที่ที่ด้านล่างของหน้า ทำงานได้ดีใน FF28.0, Chrome 34.0.1847.116 m และ IE11
user1063287

1
Flexbox ไม่ใช่เครื่องมือที่ได้รับการสนับสนุนมากที่สุดในเว็บและไม่ได้เหนือกว่าวิธีแบบดั้งเดิมของระยะขอบและแผ่นรอง
TheBlackBenzKid

สำหรับทุกคนที่กำลังมองหาการปรับหลาย divs ด้วย widht ที่ไม่ได้กำหนด: ใช้ flex-wrap กับตัวเลือก display: flex มันจะตัด divs ด้วยความกว้างแบบไดนามิก
Kamil Budziewski

20

หากcss3เป็นตัวเลือกสามารถทำได้โดยใช้calc()ฟังก์ชันcss

กรณีที่ 1: จัดชิดขอบกล่องในบรรทัดเดียว ( FIDDLE )

มาร์กอัปนั้นง่าย - กอง div ที่มีองค์ประกอบคอนเทนเนอร์บางส่วน

CSS มีลักษณะดังนี้:

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

ที่-1pxเพื่อแก้ไขข้อผิดพลาดการคำนวณ IE9 + / การปัดเศษ - ดูที่นี่

กรณีที่ 2: จัดชิดขอบกล่องในหลายบรรทัด ( FIDDLE )

ที่นี่นอกเหนือจากcalc()ฟังก์ชั่นmedia queriesมีความจำเป็น

แนวคิดพื้นฐานคือการตั้งค่าคิวรีสื่อสำหรับแต่ละ #columns ซึ่งฉันใช้ calc () เพื่อคำนวณระยะขอบขวาบนแต่ละองค์ประกอบ (ยกเว้นคอลัมน์ในคอลัมน์สุดท้าย)

ฟังดูเหมือนทำงานมาก แต่ถ้าคุณใช้ LESS หรือ SASS สามารถทำได้ค่อนข้างง่าย

(มันสามารถทำได้ด้วย css ปกติ แต่จากนั้นคุณจะต้องทำการคำนวณทั้งหมดด้วยตนเองและถ้าคุณเปลี่ยนความกว้างของกล่อง - คุณต้องคำนวณทุกอย่างอีกครั้ง)

ด้านล่างเป็นตัวอย่างการใช้น้อย: (คุณสามารถคัดลอก / วางรหัสนี้ที่นี่เพื่อเล่นกับมัน [มันเป็นรหัสที่ฉันใช้ในการสร้างซอดังกล่าวข้างต้น])

@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;
    }
}

ดังนั้นโดยพื้นฐานคุณต้องตัดสินใจเลือกความกว้างของกล่องและระยะห่างขั้นต่ำที่คุณต้องการระหว่างกล่อง

ด้วยวิธีนี้คุณสามารถคำนวณจำนวนเนื้อที่ที่คุณต้องการสำหรับแต่ละรัฐ

จากนั้นใช้ calc () เพื่อคำนวณระยะขอบด้านขวาและ n-child เพื่อลบระยะขอบด้านขวาออกจากกล่องในคอลัมน์สุดท้าย

ประโยชน์ของคำตอบมากกว่านี้คำตอบที่ได้รับการยอมรับที่ใช้text-align:justifyก็คือว่าเมื่อคุณมีมากกว่าหนึ่งแถวของกล่อง - กล่องในแถวสุดท้ายไม่ได้รับ 'ธรรม' เช่นถ้ามี 2 กล่องที่เหลืออยู่ในแถวสุดท้าย - ฉัน ไม่ต้องการให้กล่องแรกอยู่ทางซ้ายและอีกอันอยู่ทางขวา แต่ให้ทำตามกันตามลำดับ

เกี่ยวกับการรองรับเบราว์เซอร์ : สิ่งนี้จะทำงานบน IE9 +, Firefox, Chrome, Safari6.0 + - (ดูที่นี่สำหรับรายละเอียดเพิ่มเติม) อย่างไรก็ตามฉันสังเกตเห็นว่าใน IE9 + มีข้อผิดพลาดเล็กน้อยระหว่างสถานะการสืบค้นสื่อ [ถ้ามีคนรู้วิธีแก้ไขปัญหานี้ฉันอยากรู้ :)] <- คงที่นี่


13

โพสต์อื่น ๆ ได้กล่าวถึงflexboxแต่ถ้าจำเป็นต้องมีมากกว่าหนึ่งแถวรายการspace-betweenทรัพย์สินของ flexbox จะล้มเหลว (ดูที่ท้ายโพสต์)

ในวันที่ทางออกที่สะอาดเท่านั้นสำหรับเรื่องนี้คือกับ

โมดูล CSS กริดเค้าโครง ( ตัวอย่าง Codepen )

โดยทั่วไปจำเป็นต้องใช้รหัสที่เกี่ยวข้องกับสิ่งนี้:

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) ทำให้องค์ประกอบภาชนะเป็นภาชนะตาราง

2) ตั้งค่ากริดด้วยจำนวนคอลัมน์ 'อัตโนมัติ' - ตามความจำเป็น สิ่งนี้ทำเพื่อเค้าโครงตอบสนอง ความกว้างของแต่ละคอลัมน์จะเท่ากับ 120px (โปรดสังเกตการใช้auto-fit(ตามที่กำหนดauto-fill) ซึ่ง (สำหรับเลย์เอาต์ 1 แถว) ยุบแทร็กที่ว่างเปล่าเป็น 0 - ทำให้รายการขยายเพื่อใช้พื้นที่ที่เหลือ (ดูตัวอย่างนี้เพื่อดูสิ่งที่ฉันกำลังพูดถึง ))

3) กำหนดช่องว่าง / รางสำหรับแถวและคอลัมน์กริด - ที่นี่เนื่องจากต้องการเลย์เอาต์ 'ช่องว่างระหว่าง' - ช่องว่างจะเป็นช่องว่างขั้นต่ำจริง ๆเพราะมันจะเติบโตตามความจำเป็น

4) และ 5) - คล้ายกับ 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>

Codepen สาธิต (ปรับขนาดเพื่อดูผล)


สนับสนุนเบราว์เซอร์ - Caniuse

รองรับ Chrome (กะพริบ), Firefox, Safari และ Edge ในปัจจุบัน! ... ด้วยการสนับสนุนบางส่วนจาก IE (ดูโพสต์นี้โดย Rachel Andrew)


หมายเหตุ:

space-betweenคุณสมบัติของ Flexbox ใช้งานได้ดีสำหรับหนึ่งแถวของไอเท็ม แต่เมื่อนำไปใช้กับเฟล็กซ์คอนเทนเนอร์ซึ่งล้อมรอบมันเป็นไอเท็ม - (พร้อมflex-wrap: wrap) - ล้มเหลวเนื่องจากคุณไม่สามารถควบคุมการจัดเรียงของแถวสุดท้ายของรายการ แถวสุดท้ายจะถูกต้องเสมอ (โดยปกติไม่ใช่สิ่งที่คุณต้องการ)

เพื่อสาธิต:

Codepen (ปรับขนาดเพื่อดูสิ่งที่ฉันกำลังพูดถึง)


อ่านเพิ่มเติมเกี่ยวกับกริด CSS:


1
คำตอบที่มีการประเมินต่ำมาก นี่เป็นวิธีที่ง่ายและมีประสิทธิภาพที่สุดในการบรรลุสิ่งที่ฉันต้องการจะทำ ขอบคุณ.
Barnaby Mercer

1
นี่เป็น CSS ที่น้อยที่สุด (และไม่มี JS!) ที่สร้างพฤติกรรมที่ฉันต้องการอย่างแน่นอนโดยมีการปรับแต่งขนาดและพื้นที่
EKW

1
ฉันได้ค้นหาสิ่งนี้มาระยะหนึ่งแล้วก็พบว่า! ขอบคุณ @Danield
nareeboy

2

สิ่งนี้ใช้ได้กับฉันด้วย 5 ภาพในขนาดที่แตกต่างกัน

  1. สร้างกองคอนเทนเนอร์
  2. รายการที่ไม่เรียงลำดับสำหรับรูปภาพ
  3. บน css จะต้องไม่มีการเรียงลำดับในแนวตั้งและไม่มีสัญลักษณ์แสดงหัวข้อย่อย
  4. ปรับเนื้อหาของคอนเทนเนอร์ div

สิ่งนี้ได้ผลเพราะ justify-content: ช่องว่างระหว่างและอยู่ในรายการแสดงในแนวนอน

บน CSS

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

บน 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>

ในขณะที่รหัสนี้อาจใช้งานได้ดีคำตอบที่ดีจะมีคำอธิบายว่ามันทำงานอย่างไรและทำไมจึงเป็นทางออกที่ดี
Blackwood

มันเป็นมูลค่า noting flexbox ที่ไม่ได้ (หรือเพียงบางส่วนเท่านั้น) สนับสนุนโดย IE caniuse.com/#feat=flexbox
เดวิด Salamon

ตอบสนองนี้หรือไม่
stackdave

1

ในjQueryคุณอาจกำหนดเป้าหมายผู้ปกครองโดยตรง

สิ่งนี้มีประโยชน์หากคุณไม่ทราบว่าเด็ก ๆ จะถูกเพิ่มเข้าแบบไดนามิกหรือหากคุณไม่สามารถหาตัวเลขของพวกเขาได้

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);

สิ่งนี้จะทำให้การparentเติบโตในแนวนอนเป็นไปchildrenได้

หมายเหตุ: นี่ถือว่า'.children'มีwidthและHeightตั้ง

หวังว่าจะช่วย


1

หากคุณทราบจำนวนองค์ประกอบต่อ "แถว" และความกว้างของคอนเทนเนอร์คุณสามารถใช้ตัวเลือกเพื่อเพิ่มระยะขอบให้กับองค์ประกอบที่คุณต้องทำให้เกิดลักษณะที่เป็นธรรม

ฉันมีแถวของสาม divs ที่ฉันต้องการให้เป็นธรรมใช้:

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

สิ่งนี้ทำให้ div กลางในแต่ละแถวมีระยะขอบที่บังคับให้ div 1 และ 3 ไปที่ขอบด้านนอกของคอนเทนเนอร์

ยังยอดเยี่ยมสำหรับสิ่งอื่น ๆ เช่นสีพื้นหลังของเส้นขอบ ฯลฯ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.