ข้ามไปยังเนื้อหา

CSS Grid — Layout สองมิติ

Flexbox จัดการทีละทิศทาง CSS Grid จัดการ ทั้งสอง อย่างพร้อมกัน — แถวและคอลัมน์พร้อมกัน ถ้าคุณเคยตั้ง layout grid ใน Figma เพื่อให้คอลัมน์สอดคล้องกันในทุกหน้าจอ CSS Grid คือสิ่งที่ทำให้สิ่งนั้นเป็นจริงใน browser

ความแตกต่างสำคัญจาก Flexbox: กับ Grid parent จะกำหนดโครงสร้างสองมิติทั้งหมด children เพียงแค่เข้าไปในตำแหน่ง

display: grid — เปิดใช้งาน Grid บน parent container

grid-template-columns — กำหนดโครงสร้างคอลัมน์ นี่คือ Grid property ที่สำคัญที่สุด

grid-template-columns: 200px 1fr 1fr; /* คงที่ + สองคอลัมน์ยืดหยุ่น */
grid-template-columns: repeat(3, 1fr); /* สามคอลัมน์เท่ากัน */
grid-template-columns: repeat(4, 1fr); /* สี่คอลัมน์เท่ากัน — เหมือน 4-col Figma grid */

fr — หน่วย fractionalfr หมายถึง “ส่วนหนึ่งของพื้นที่ที่มี” หนึ่ง 1fr ได้หนึ่งส่วน สองคอลัมน์ที่ 1fr 2fr หมายความว่าอันที่สองกว้างเป็นสองเท่าของอันแรก นี่คือแนวคิดเดียวกับการ sizing แบบสัดส่วน “fill container” ของ Figma

gap — พื้นที่ระหว่างแถวและคอลัมน์ คุณสามารถตั้งทั้งคู่พร้อมกัน (gap: 1rem) หรือแยกกัน (row-gap: 1rem; column-gap: 2rem)

grid-template-areas — ตั้งชื่อให้กับส่วนต่างๆ ของ grid แล้วกำหนด elements ให้กับชื่อเหล่านั้น นี่เป็นมิตรกับนักออกแบบมาก — คุณกำลัง วาด layout ตามตัวอักษร

grid-template-areas:
"header header"
"sidebar main"
"footer footer";

แล้วบน child แต่ละอัน: grid-area: header; / grid-area: sidebar; เป็นต้น

ด้านล่างคือ dashboard grid แบบคลาสสิก ลองเปลี่ยนจำนวนคอลัมน์, ค่า fr หรือ gap

สิ่งที่ลองได้:

  • เปลี่ยน grid-template-columns: 200px 1fr เป็น 1fr 3fr — sidebar กลายเป็นแบบสัดส่วน
  • เปลี่ยน gap เป็น 2rem แล้วดูพื้นที่หายใจเพิ่มขึ้น
  • เปลี่ยน grid-template-columns เป็น 300px 1fr เพื่อขยาย sidebar
  • จัดเรียง grid-template-areas ใหม่เพื่อย้าย sidebar ไปด้านขวา

นี่คือกรณีการใช้งานที่พบบ่อยกว่า — image gallery แบบ responsive ด้วย repeat():

ลองเปลี่ยน repeat(3, 1fr) เป็น repeat(2, 1fr) หรือ repeat(4, 1fr)

  • ใช้ Flexbox ฝืนทำ 2 มิติ (แถวและคอลัมน์พร้อมกัน) ทั้งที่ Grid ทำได้ตรงกว่า
  • ลืมว่า Grid ต้องกำหนด track ทั้งแถวและคอลัมน์ล่วงหน้าใน grid-template-columns/grid-template-rows

Designer เห็น “ตาราง Dashboard/Gallery” แต่ developer เลือก Grid เมื่อ layout เป็น 2 มิติจริง (แถวและคอลัมน์ต้องสัมพันธ์กัน) แทนใช้ Flexbox ที่ทำได้ดีแค่ 1 มิติ

💡 ตัวอย่างจากของจริง

Dashboard อย่าง Stripe และ Vercel ใช้ CSS Grid สำหรับ layout การ์ด metric ที่ต้อง align กันทั้งแถวและคอลัมน์พร้อมกัน

`grid-template-columns: repeat(4, 1fr)` สร้างอะไร?
หน่วย `fr` หมายถึงอะไร?
property ใดที่กำหนด grid child ให้กับ named area ที่กำหนดไว้ใน grid-template-areas?
ข้อได้เปรียบหลักของ CSS Grid เหนือ Flexbox คืออะไร?