เหตุใดช่องว่างคอลัมน์ของฉันจึงเล็กลงเมื่อฉันเพิ่มความกว้างของคอนเทนเนอร์

Jan 06 2021

ฉันมีปัญหาในการทำความเข้าใจตรรกะเบื้องหลังช่องว่างของคอลัมน์ในเค้าโครงหลายคอลัมน์ ฉันมี HTML / CSS ต่อไปนี้ในFiddle นี้ :

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
</div>
.flex-container {
  height: 500px;
  width: 300px;
  border: 1px solid blue;
  columns: 120px;
  padding: 10px;
}

.flex-item {
  background: OliveDrab;
  padding: 5px;
  width: 100px;
  height: 100px;
  line-height: 100px;
  color: white;
  text-align: center;
  break-inside: avoid-column;
}

คุณจะสังเกตเห็นว่าถ้าคุณเปลี่ยนwidthคอนเทนเนอร์จาก 300px เป็น 400px ช่องว่างระหว่างคอลัมน์จะลดลงจริงๆ

ทำไมมันถึงทำเช่นนี้? เป็นไปได้ไหมที่จะจัดแนวคอลัมน์ไปทางซ้ายเพื่อไม่ให้เคลื่อนไปมา ช่องว่างคงที่ระหว่างคอลัมน์ CSSอาจแนะนำว่าเป็นไปไม่ได้

คำตอบ

2 TemaniAfif Jan 06 2021 at 23:12

เค้าโครงคอลัมน์ค่อนข้างยุ่งยากเล็กน้อย หากคุณอ่านข้อกำหนดที่เกี่ยวข้องcolumn-widthคุณสามารถค้นหา:

อธิบายความกว้างของคอลัมน์ที่เหมาะสมที่สุด ความกว้างของคอลัมน์จริงอาจกว้างกว่า (เพื่อเติมเต็มพื้นที่ว่าง) หรือแคบลง (เฉพาะในกรณีที่พื้นที่ว่างน้อยกว่าความกว้างของคอลัมน์ที่ระบุ อ้างอิง

ลบความกว้างออกจากองค์ประกอบและปรับขนาดคอนเทนเนอร์เพื่อสังเกตสิ่งนี้:

.flex-container {
  width: 400px;
  border: 1px solid blue;
  columns: 120px;
  padding: 10px;
  overflow:hidden;
  resize:horizontal;
}

.flex-item {
  background: OliveDrab;
  padding: 5px;
  height: 100px;
  line-height: 100px;
  color: white;
  text-align: center;
  break-inside: avoid-column;
}
<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
</div>

คุณจะสังเกตเห็นว่าช่องว่างได้รับการแก้ไขแล้ว แต่ความกว้างของคอลัมน์กำลังเปลี่ยนไป

คุณสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับอัลกอริทึมได้ที่นี่: https://drafts.csswg.org/css-multicol-1/#pseudo-algorithm


วิธีแก้ปัญหาคือการพิจารณาการใช้ CSS grid ที่มีความกว้างของคอลัมน์คงที่ เคล็ดลับคือการกำหนดความกว้างของคอลัมน์กริดให้เท่ากับช่องว่าง + ความกว้างของคอลัมน์และคุณทำให้คอนเทนเนอร์เติมคอลัมน์ทั้งหมด (ความกว้างจะเป็นตัวคูณของช่องว่าง + ความกว้างของคอลัมน์ )

ปรับขนาดหน้าจอเพื่อดูผลลัพธ์:

.container {
  display:grid;
  grid-template-columns:repeat(auto-fit,140px); /* 120 + 20 */
  overflow: hidden;
  resize: horizontal;
  border: 1px solid blue;

}

.flex-container {
  grid-column:1/-1;
  column-width: 120px;
  column-gap: 20px;
  padding: 10px;
}

.flex-item {
  background: OliveDrab;
  padding: 5px;
  height: 100px;
  line-height: 100px;
  color: white;
  text-align: center;
  break-inside: avoid-column;
}
<div class="container">
  <div class="flex-container">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    <div class="flex-item">7</div>
    <div class="flex-item">8</div>
    <div class="flex-item">9</div>
    <div class="flex-item">10</div>
  </div>
</div>

3 AHaworth Jan 06 2021 at 23:03

หากคุณไม่ได้ระบุจำนวนคอลัมน์ (พารามิเตอร์ที่สองเป็นคอลัมน์) ระบบจะคำนวณจำนวนคอลัมน์ที่เป็นไปได้ (กล่าวคือใช้อัตโนมัติเป็นพารามิเตอร์การนับคอลัมน์)

คุณได้ระบุความกว้างคอลัมน์ 'อุดมคติ' ไว้ที่ 120px และรายการจริงมีความกว้างน้อยกว่านั้น ดังนั้นระบบจึงคิดว่าคุณจะได้ 3 คอลัมน์ในคอนเทนเนอร์ที่มีความกว้าง 400px และวางสองคอลัมน์แรกตามนั้น

นี่คือข้อมูลบางส่วนจาก https://developer.mozilla.org/en-US/docs/Web/CSS/column-width

คุณสมบัติ CSS ความกว้างของคอลัมน์ตั้งค่าความกว้างของคอลัมน์ในอุดมคติในเค้าโครงหลายคอลัมน์ คอนเทนเนอร์จะมีคอลัมน์มากที่สุดเท่าที่จะใส่ได้โดยที่ไม่มีคอลัมน์ใดที่มีความกว้างน้อยกว่าค่าความกว้างของคอลัมน์ หากความกว้างของคอนเทนเนอร์แคบกว่าค่าที่ระบุความกว้างของคอลัมน์เดียวจะน้อยกว่าความกว้างของคอลัมน์ที่ประกาศไว้

หากคุณต้องการให้แน่ใจว่ามีเพียงสองคอลัมน์ให้ระบุพารามิเตอร์ที่สอง:

columns: 120px 2;

.flex-container {
  height: 500px;
  width: 400px;
  border: 1px solid blue;
  columns: 120px 2;
  padding: 10px;
}

.flex-item {
  background: OliveDrab;
  padding: 5px;
  width: 100px;
  height: 100px;
  line-height: 100px;
  color: white;
  text-align: center;
  break-inside: avoid-column;
}
<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
</div>