วิธีทำให้ flexbox มีขนาดเท่ากัน?


186

ฉันต้องการใช้ flexbox ที่มีจำนวนรายการที่มีความกว้างเท่ากันทั้งหมด ฉันสังเกตว่าเฟล็กบ็อกซ์กระจายพื้นที่รอบ ๆ อย่างสม่ำเสมอมากกว่าพื้นที่

ตัวอย่างเช่น:

.header {
  display: flex;
}

.item {
  flex-grow: 1;
  text-align: center;
  border: 1px solid black;
}
<div class="header">
  <div class="item">asdfasdfasdfasdfasdfasdf</div>
  <div class="item">z</div>
</div>

รายการแรกมีขนาดใหญ่กว่าชิ้นที่สองมาก ถ้าฉันมี 3 รายการ 4 รายการหรือ n รายการฉันต้องการให้พวกเขาทั้งหมดปรากฏในบรรทัดเดียวกันด้วยจำนวนช่องว่างต่อรายการเท่ากัน

ความคิดใด ๆ

http://codepen.io/anon/pen/gbJBqM

คำตอบ:


287

ตั้งค่าให้flex-basisเป็น0(องค์ประกอบทั้งหมดมีจุดเริ่มต้นเหมือนกัน) และอนุญาตให้เติบโต:

flex: 1 1 0px

IDE หรือ linter ของคุณอาจพูดถึงสิ่งthe unit of measure 'px' is redundantนั้น หากคุณปล่อยไว้ (เช่นflex: 1 1 0:) IE จะแสดงผลไม่ถูกต้อง ดังนั้นpxจำเป็นต้องมีการสนับสนุน Internet Explorer ตามที่ระบุไว้ในความคิดเห็นโดย @fabb;


65
มันควรจะตั้งข้อสังเกตว่าflexคุณสมบัติเป็นที่พักจดชวเลขสำหรับflex-grow, flex-shrinkและflex-basisคุณสมบัติ ขอแนะนำให้ใช้ชวเลขและมากกว่าคุณสมบัติแต่ละอันเนื่องจากชวเลขและรีเซ็ตองค์ประกอบที่ไม่ได้รับการระบุใด ๆ อย่างถูกต้องเพื่อรองรับการใช้งานทั่วไป 0 1 autoค่าเริ่มต้นคือ
j08691

3
โปรดทราบว่า IE11 จะไม่สนใจค่า flex-based แบบไม่มีหน่วย: github.com/philipwalton/flexbugs#flexbug-4
fabb

9
ฉันต้องเพิ่มmin-width: 0เพื่อให้บรรลุการใช้องค์ประกอบของเด็กที่มีข้อความล้น ดูcss-tricks.com/flexbox-truncated-text
Iwazaru

78

คุณสามารถเพิ่มflex-basis: 100%เพื่อให้บรรลุสิ่งนี้

อัปเดตตัวอย่าง

.header {
  display: flex;
}

.item {
  flex-basis: 100%;
  text-align: center;
  border: 1px solid black;
}

สำหรับสิ่งที่คุ้มค่าคุณสามารถใช้flex: 1เพื่อผลลัพธ์เดียวกันได้เช่นกัน

การจดชวเลขflex: 1เหมือนกันflex: 1 1 0ซึ่งเทียบเท่ากับ:

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
  text-align: center;
  border: 1px solid black;
}

1
สิ่งนี้ไม่ถูกต้อง flex: 0 1 autoค่าดิ้นเริ่มต้นคือ ซึ่งการตั้งค่าวิธีการจะส่งผลให้flex: 1 flex: 1 1 autoสิ่งนี้จะไม่ทำงาน คำตอบที่ถูกต้องเป็นไปflex: 1 1 0ตามที่ระบุไว้ข้างต้นโดย Adam
r.sendecky

17
@ r.sendecky ไม่คุณเป็นคนที่ไม่ถูกต้อง ขณะที่ผมระบุไว้ในคำตอบของฉัน, ชวเลขของflex: 1ผลในการflex: 1 1 0 ไม่ flex: 1 1 autoเหมือนกับที่คุณอ้างสิทธิ์ ลองดูที่สเป W3 อย่างเป็นทางการภายใต้การส่วน 'ดิ้นชวเลข' : เมื่อflex-basisมีการ "ตัดออกจากชวเลขดิ้นค่ากำหนดของมันคือ0" autoไม่ได้ ขอบคุณสำหรับการโหวตลงแบบสุ่ม
Josh Crozier

2
@ r.sendecky - นอกจากนี้ลองดูตัวอย่างนี้ที่ฉันสร้างขึ้นเพื่อให้เห็นภาพชุดรูปแบบ
Josh Crozier

1
เพื่อนฉันไม่สุ่มลงคะแนน ฉันทดสอบก่อนเขียน และฉันก็ทำการทดสอบ คำตอบของคุณไม่ทำงาน - ง่ายเหมือนที่ ฉันได้ว่าปัญหาเดียวกันไม่นานมานี้ด้วยและflex: 1 flex-direction: columnความสูงของเด็กนั้นไม่เหมือนกันเมื่อวางองค์ประกอบอื่นไว้ภายในเด็ก flex: 1 1 0สิ่งเดียวที่คงมันคือการตั้งค่า มันยังคงยืนอยู่ในวันนี้ด้วยโครเมียม 55.0.2883.87
r.sendecky

4
@JoshCrozier ยืนยันว่า flex: 1มีพฤติกรรมเช่นเดียวกับflex: 1 1 0และflex: 0 1 autoมีพฤติกรรมที่แตกต่างกัน
Ivan Durst

66

คุณต้องเพิ่มwidth: 0เพื่อทำให้คอลัมน์เท่ากันถ้าเนื้อหาของรายการทำให้ใหญ่ขึ้น

.item {
  flex: 1 1 0;
  width: 0;
}

5
สิ่งนี้ดูเหมือนจะมีความจำเป็นหากเนื้อหาที่.itemทำให้มันกว้างขึ้นกว่า.itemปกติ
Bungle

1
ฉันคิดว่าคุณหมายถึงflex: 1 1 0;แทนที่จะเป็นflex-grow: 1 1 0;
Chicken Soup

3
fyi, ลิงก์เสีย
Bobby Jack

การตั้งค่าflex-basisเพื่อ0จุดมุ่งหมายเดียวกับการตั้งค่าไปwidth 0
สตีเฟ่น

ในกรณีที่ใช้งานของฉันฉันกำลังห่อแผนภูมิที่ปรับให้พอดีกับขนาดและความกว้าง 0 ของผู้ปกครองเป็นสิ่งจำเป็นสำหรับพวกเขาในการทำงาน ฉันไม่แน่ใจว่าพวกเขากำหนดความกว้างที่เหมาะสมอย่างไร แต่พื้นฐานที่ยืดหยุ่นไม่ได้ใช้กับ chrome 72 อย่างแน่นอน (เผยแพร่เมื่อมกราคม 2019)
Andy Groff

12

คำตอบที่ยอมรับโดย Adam (flex: 1 1 0 ) ทำงานได้อย่างสมบูรณ์แบบสำหรับบรรจุภัณฑ์แบบเฟล็กบ็อกซ์ที่มีความกว้างคงที่หรือกำหนดโดยบรรพบุรุษ สถานการณ์ที่คุณต้องการให้เด็ก ๆ พอดีกับภาชนะ

อย่างไรก็ตามคุณอาจมีสถานการณ์ที่คุณต้องการให้ภาชนะบรรจุพอดีกับเด็กโดยที่เด็ก ๆ จะมีขนาดเท่ากันตามขนาดของเด็กที่ใหญ่ที่สุด คุณสามารถสร้างคอนเทนเนอร์ flexbox ให้เหมาะกับลูกของมันได้โดย:

  • การตั้งค่าposition: absoluteและไม่ได้ตั้งค่าwidthหรือrightหรือ
  • วางไว้ในเสื้อคลุมด้วย display: inline-block

สำหรับคอนเทนเนอร์ flexbox ดังกล่าวคำตอบที่ยอมรับไม่ทำงานเด็ก ๆ จะมีขนาดไม่เท่ากัน ฉันคิดว่านี่เป็นข้อ จำกัด ของ flexbox เนื่องจากมันทำงานเหมือนกันใน Chrome, Firefox และ Safari

การแก้ปัญหาคือการใช้กริดแทน flexbox

การสาธิต: https://codepen.io/brettdonald/pen/oRpORG

<p>Normal scenario — flexbox where the children adjust to fit the container — and the children are made equal size by setting {flex: 1 1 0}</p>

<div id="div0">
  <div>
    Flexbox
  </div>
  <div>
    Width determined by viewport
  </div>
  <div>
    All child elements are equal size with {flex: 1 1 0}
  </div>
</div>

<p>Now we want to have the container fit the children, but still have the children all equally sized, based on the largest child. We can see that {flex: 1 1 0} has no effect.</p>

<div class="wrap-inline-block">
<div id="div1">
  <div>
    Flexbox
  </div>
  <div>
    Inside inline-block
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
</div>

<div id="div2">
  <div>
    Flexbox
  </div>
  <div>
    Absolutely positioned
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>

<br><br><br><br><br><br>
<p>So let's try a grid instead. Aha! That's what we want!</p>

<div class="wrap-inline-block">
<div id="div3">
  <div>
    Grid
  </div>
  <div>
    Inside inline-block
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
</div>

<div id="div4">
  <div>
    Grid
  </div>
  <div>
    Absolutely positioned
  </div>
  <div>
    We want all children to be the size of this text
  </div>
</div>
body {
  margin: 1em;
}

.wrap-inline-block {
  display: inline-block;
}

#div0, #div1, #div2, #div3, #div4 {
  border: 1px solid #888;
  padding: 0.5em;
  text-align: center;
  white-space: nowrap;
}

#div2, #div4 {
  position: absolute;
  left: 1em;
}

#div0>*, #div1>*, #div2>*, #div3>*, #div4>* {
  margin: 0.5em;
  color: white;
  background-color: navy;
  padding: 0.5em;
}

#div0, #div1, #div2 {
  display: flex;
}

#div0>*, #div1>*, #div2>* {
  flex: 1 1 0;
}

#div0 {
  margin-bottom: 1em;
}

#div2 {
  top: 15.5em;
}

#div3, #div4 {
  display: grid;
  grid-template-columns: repeat(3,1fr);
}

#div4 {
  top: 28.5em;
}

0

ฉันไม่มีความเชี่ยวชาญในการยืดหยุ่น แต่ฉันไปถึงที่นั่นด้วยการตั้งค่าพื้นฐานเป็น 50% สำหรับสองรายการที่ฉันติดต่อด้วย เพิ่มเป็น 1 และลดขนาดเป็น 0

สไตล์อินไลน์: flex: '1 0 50%',

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