Kodokon kodokon.com

กริดระดับผู้เชี่ยวชาญ: subgrid, auto-fit และ minmax

สร้างกริดที่ปรับตัวได้เองโดยไม่ต้องใช้ media queries และจัดแนวคอมโพเนนต์ที่ซ้อนกันให้ตรงกับแทร็กของพาเรนต์ด้วย subgrid

10 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

repeat(auto-fill, ...) และ repeat(auto-fit, ...) จะสร้างแทร็กจำนวนมากเท่าที่ความกว้างของคอนเทนเนอร์จะเอื้ออำนวย ความแตกต่างจะปรากฏก็ต่อเมื่อมี จำนวนไอเทมน้อยกว่าจำนวนแทร็กที่เป็นไปได้ เท่านั้น: auto-fill จะคงแทร็กว่างเอาไว้ (การ์ดสองใบของคุณจะอยู่ที่ขนาดต่ำสุด โดยมีพื้นที่ว่างทางด้านขวา) ในขณะที่ auto-fit จะ ยุบแทร็กว่างให้เหลือศูนย์ แทร็กที่ถูกใช้งานซึ่งมีค่าสูงสุดเป็น 1fr จะดูดซับพื้นที่ที่ว่างออกมาทั้งหมด และการ์ดสองใบของคุณจะยืดขยายเต็มความกว้าง

CSS
.gallery-fill {
  display: grid;
  grid-template-columns: repeat(
    auto-fill, minmax(150px, 1fr)
  );
}
.gallery-fit {
  display: grid;
  grid-template-columns: repeat(
    auto-fit, minmax(150px, 1fr)
  );
}
เมื่อมี 2 ไอเทมในพื้นที่ 900px: fill จะคง 6 แทร็ก (เต็ม 2 ว่าง 4) ส่วน fit จะยุบแทร็กว่างและยืด 2 ไอเทมออก

มีกับดักของ minmax() สองอย่างที่แม้แต่นักพัฒนาระดับซีเนียร์ก็ยังตกลงไป อย่างแรก: minmax(240px, 1fr) จะล้น (overflow) เมื่อคอนเทนเนอร์แคบกว่า 240px เพราะค่าต่ำสุดเป็นพื้นแข็งที่ตายตัว วิธีแก้แบบสำนวนคือซ้อนฟังก์ชันเปรียบเทียบลงไป: minmax(min(100%, 240px), 1fr) อย่างที่สอง: 1fr เดี่ยว ๆ เทียบเท่ากับ minmax(auto, 1fr); ค่าต่ำสุดที่เป็น auto จะยอมให้เนื้อหาที่ตัดคำไม่ได้ (URL ยาว ๆ หรือ <pre>) ขยายแทร็กให้กว้างเกินส่วนแบ่งของมัน minmax(0, 1fr) จะล็อกการกระจายพื้นที่ไว้

CSS
.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(100%, 240px), 1fr)
  );
}
กริดแบบ responsive มาตรฐานที่ไม่ต้องใช้ media query: ไม่มีวันล้น แม้จะแคบกว่า 240px

subgrid แก้ปัญหาเก่าแก่เรื่องการจัดแนวข้ามคอมโพเนนต์ที่ซ้อนกัน ด้วย grid-template-rows: subgrid กริดภายในจะไม่สร้างแทร็กของตัวเองขึ้นมา แต่จะ รับเอาแทร็กของพาเรนต์มาใช้ ในพื้นที่ที่มันครอบคลุมอยู่ มันยังสืบทอดชื่อเส้น (line names) ของพาเรนต์มาด้วย (และสามารถเพิ่มชื่อของตัวเองได้) เช่นเดียวกับ gap ที่มันสามารถเขียนทับในระดับท้องถิ่นได้ กรณีคลาสสิกคือ: การ์ดที่มีหัวข้อ คำอธิบาย และส่วนท้าย ต้องจัดแนวในแนวนอนให้ตรงกันจากการ์ดหนึ่งไปยังอีกการ์ดหนึ่ง ไม่ว่าเนื้อหาจะยาวเท่าใดก็ตาม ซึ่งเป็นสิ่งที่ทำให้เรียบร้อยได้ยากก่อนที่จะมี subgrid เพราะการ์ดแต่ละใบคำนวณความสูงของตัวเองแยกกันโดยลำพัง

CSS
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
.card {
  grid-row: span 3;
  display: grid;
  grid-template-rows: subgrid;
  row-gap: 0.5rem;
}
การ์ดแต่ละใบครอบคลุม 3 แถวของพาเรนต์และรับมาใช้: หัวข้อ ข้อความ และส่วนท้ายจัดแนวตรงกันข้ามการ์ด

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. คอนเทนเนอร์สามารถบรรจุได้ 6 แทร็ก แต่มีเพียง 2 ไอเทม ความแตกต่างระหว่าง auto-fill และ auto-fit คืออะไร?
    • ไม่มีความแตกต่าง ทั้งสองเป็นชื่อพ้องของค่าเดียวกัน
    • auto-fill คงแทร็กว่างไว้ 4 แทร็ก ส่วน auto-fit ยุบมันและ 2 ไอเทมยืดออก
    • auto-fit สร้างแทร็กมากกว่า auto-fill เสมอ
  2. เอลิเมนต์ที่ประกาศด้วย grid-template-rows: subgrid รับเอาสิ่งใดมาใช้อย่างแท้จริง?
    • เพียงจำนวนแถวของพาเรนต์เท่านั้น
    • ขนาดแทร็กและชื่อเส้นของพาเรนต์ในพื้นที่ที่ครอบคลุม โดยสืบทอด gap มาแต่เขียนทับได้
    • คุณสมบัติกริดทั้งหมดของพาเรนต์ รวมถึงพื้นที่ที่ตั้งชื่อไว้ด้วย
  3. เหตุใดจึงเขียน minmax(min(100%, 240px), 1fr) แทนที่จะเป็น minmax(240px, 1fr)?
    • เพื่อรับประกันว่าจะได้ 240px บนทุกหน้าจอ
    • เพื่อหลีกเลี่ยงการล้นเมื่อคอนเทนเนอร์แคบกว่า 240px
    • เพราะ min() เป็นสิ่งบังคับภายใน repeat() ตั้งแต่ Grid Level 2 เป็นต้นมา