CSS
Grid
gap
เรียนรู้วิธีกำหนดระยะห่างระหว่าง grid items ด้วย gap — property เดียวที่ทำให้ layout ดูเป็นระเบียบโดยไม่ต้องไปใส่ margin ทุก item
หัวข้อนี้คืออะไร
หลังจากกำหนด display: grid และ grid-template-columns แล้ว items จะถูกวางในช่องคอลัมน์ แต่ยังเบียดชิดกันโดยไม่มีช่องว่าง gap คือ property ที่บอก browser ว่า "ให้เว้นระยะห่างระหว่าง grid items เท่านี้" gap กำหนดที่ Grid Container (parent) — ไม่ใช่ที่ item แต่ละชิ้น เมื่อกำหนดแล้ว browser จะแทรกช่องว่างระหว่าง items ทุกคู่โดยอัตโนมัติ ทั้งในแนวแถวและแนวคอลัมน์ สิ่งสำคัญที่ต้องจำ: - gap กำหนดที่ parent (Grid Container) ไม่ใช่ที่ child - gap สร้างช่องว่างระหว่าง items เท่านั้น ไม่เพิ่มพื้นที่ที่ขอบนอก container - gap: 16px คือ shorthand ของ row-gap: 16px + column-gap: 16px - ต้องมี display: grid ก่อน gap ถึงจะมีผล
- gap กำหนดระยะห่างระหว่าง grid items ที่ Grid Container
- gap ทำงานทั้งแนวแถว (row) และแนวคอลัมน์ (column) พร้อมกัน
- gap: 16px = row-gap: 16px และ column-gap: 16px
- ช่องว่างเกิดเฉพาะระหว่าง items — ไม่มีผลที่ขอบนอก container
- กำหนดที่ parent เดียว แทนการใส่ margin ทุก item
ทำไมหัวข้อนี้จึงสำคัญ
วิธีเก่าในการสร้างช่องว่างระหว่าง items คือใส่ margin ที่ item แต่ละชิ้น ซึ่งมีปัญหาหลายอย่าง: margin ที่ item ขอบนอกจะเกินออกมา ต้องใช้ negative margin แก้ | margin ของ items ที่อยู่ติดกันบวกเข้าหากัน (double margin) | ต้องระบุ margin ซ้ำ ๆ ทุก item gap แก้ปัญหาเหล่านั้นทั้งหมดด้วยบรรทัดเดียว:
- ไม่ต้องใส่ margin ทุก item — กำหนดที่ container เดียวครอบคลุมทั้งหมด
- ไม่มีปัญหา double margin — gap เป็น space ระหว่าง items จริง ๆ ไม่ใช่ margin ของแต่ละชิ้น
- ไม่มีช่องว่างที่ขอบนอก container — gap ไม่เพิ่มพื้นที่รอบ container
- ปรับค่าจากที่เดียว — เปลี่ยน gap ค่าเดียวแล้วทั้ง layout อัปเดต
- อ่านโค้ดง่ายขึ้น — เห็นได้ทันทีว่า layout นี้มีช่องว่างเท่าไร
ตัวอย่างจากชีวิตจริง
ลองนึกถึงการปูกระเบื้องในห้องน้ำ ช่างไม่ได้ทา "กาว" ที่กระเบื้องแต่ละแผ่นให้หนาขึ้น แต่ใช้ ยาแนวกระเบื้อง (grout) ที่คั่นระหว่างแผ่นกระเบื้องทุกคู่ให้เท่ากัน ผลลัพธ์คือช่องว่างสม่ำเสมอทุกคู่ — ไม่ว่าจะเป็นคู่ไหน ระยะห่างก็เท่ากันหมด และกระเบื้องแผ่นสุดท้ายก็ไม่มียาแนวที่ขอบห้อง gap ทำงานแบบเดียวกัน: คุณบอก container ว่า "ใช้ช่องว่าง 16px ระหว่าง items ทุกคู่" แล้ว browser จัดการให้เองทั้งหมด
แนวคิดหลักที่ต้องเข้าใจ
gap มีสามรูปแบบ: gap (shorthand) กำหนดระยะห่างทั้งแนวแถวและคอลัมน์พร้อมกัน gap: 16px; → ช่องว่างทุกทิศทาง 16px เท่ากัน gap: 24px 12px; → row-gap 24px, column-gap 12px row-gap กำหนดเฉพาะระยะห่างระหว่างแถว (บนลงล่าง) row-gap: 24px; → ช่องว่างระหว่างแถว 24px column-gap กำหนดเฉพาะระยะห่างระหว่างคอลัมน์ (ซ้ายขวา) column-gap: 12px; → ช่องว่างระหว่างคอลัมน์ 12px กฎสำคัญ: gap สร้างช่องว่างระหว่าง items เท่านั้น ไม่มีช่องว่างที่ขอบด้านนอก container ถ้าต้องการ padding รอบนอกต้องใช้ padding ที่ container แยกต่างหาก
gap กำหนดที่ Grid Container | ช่องว่างเกิดระหว่าง items เท่านั้น | gap: row column หรือแยก row-gap / column-gap
การทำงานทีละขั้นตอน
นี่คือขั้นตอนการเพิ่มช่องว่างระหว่าง grid items:
- 1. ตรวจสอบว่า parent มี display: grid แล้ว — gap ต้องการ grid context ก่อนเสมอ
- 2. ตรวจสอบว่ากำหนด grid-template-columns แล้ว — เพื่อให้เห็น layout ที่ชัดเจนก่อนเพิ่ม gap
- 3. เพิ่ม gap ที่ parent — เขียน gap: 16px; ใน CSS ของ container
- 4. browser แทรกช่องว่าง — ทุกคู่ items ที่อยู่ติดกันจะมีช่องว่าง 16px คั่น ทั้งแนวนอนและแนวตั้ง
- 5. ปรับค่าถ้าต้องการแยก — ใช้ row-gap และ column-gap ถ้าต้องการระยะห่างแนวนอนและแนวตั้งต่างกัน
ตัวอย่างเชิงเทคนิค — ก่อนและหลัง gap
ลองดูความแตกต่างระหว่างกริดที่ไม่มี gap กับกริดที่มี gap โค้ดด้านล่างมีกล่องสี่ใบใน .without-gap และ .with-gap .without-gap ไม่มีช่องว่าง items เบียดชิดกัน .with-gap มี gap: 16px ทุก items มีช่องว่างสม่ำเสมอ ลองแก้ค่า gap ใน .with-gap แล้วสังเกตความเปลี่ยนแปลง
จุดที่ผู้เริ่มต้นมักสับสน
ตรวจสอบว่าคุณเข้าใจถูกต้องหรือยัง:
- ❌ ใส่ gap ที่ child แทน container — gap ต้องกำหนดที่ Grid Container เสมอ ถ้าใส่ที่ item มันจะเป็น gap ของ grid ที่อยู่ภายใน item นั้น ไม่ใช่ระยะห่างระหว่าง item กับพี่น้อง
- ❌ คิดว่า gap เหมือน margin — ความต่างสำคัญคือ gap ไม่เพิ่มพื้นที่ที่ขอบนอก container แต่ margin ที่ item ขอบนอกจะเกินออกมา gap จึงไม่ทำให้ layout ล้นออกนอก container
- ❌ ลืมว่า gap ต้องการ display: grid ก่อน — ถ้าไม่มี display: grid ที่ parent gap จะไม่มีผลใด ๆ ต้องมี grid context ก่อนเสมอ
- ❌ สับสน gap shorthand กับ gap สองค่า — gap: 16px ทำให้ทุกทิศทาง 16px แต่ gap: 24px 12px คือ row-gap 24px และ column-gap 12px (เหมือน padding shorthand top/bottom left/right)
เปรียบเทียบ gap กับ margin บน item
ทั้งสองสร้างช่องว่างได้ แต่พฤติกรรมต่างกันมาก:
| คุณสมบัติ | gap (ที่ container) | margin (ที่แต่ละ item) |
|---|---|---|
| กำหนดที่ | Grid Container (parent) — ที่เดียว | แต่ละ item — ทุกชิ้น |
| ช่องว่างที่ขอบนอก | ไม่มี — gap เกิดระหว่าง items เท่านั้น | มี — margin ที่ item ขอบสุดเกินออกนอก container |
| ปัญหา double space | ไม่มี — gap เป็นช่องว่างจริงระหว่างคู่ | มี — margin item A + margin item B = ช่องว่างสองเท่า |
| เมื่อต้องการเปลี่ยนค่า | แก้ที่ container เดียว ทั้ง layout อัปเดต | ต้องแก้ CSS ของ item ทุกชิ้น |
สรุปท้ายบท
จำง่าย ๆ แบบนี้: "gap กำหนดที่ parent สร้างช่องว่างระหว่าง items ทุกคู่โดยไม่แตะ child"
- gap กำหนดที่ Grid Container ร่วมกับ display: grid เสมอ
- gap: 16px = ช่องว่าง 16px ระหว่าง items ทุกคู่ ทุกทิศทาง
- gap: 24px 12px = row-gap 24px + column-gap 12px
- ใช้ row-gap และ column-gap เมื่อต้องการแยกควบคุมแนวตั้งและแนวนอน
- gap ไม่เพิ่มช่องว่างที่ขอบนอก container — ต่างจาก margin
- เปลี่ยนค่าที่ container เดียว ทั้ง layout อัปเดตพร้อมกัน
Lab 1: เพิ่ม gap ให้กริด
ชื่อ Lab: เพิ่มช่องว่างระหว่าง Grid Items เป้าหมาย: เพิ่ม gap ให้ .grid เพื่อให้ items มีช่องว่างสม่ำเสมอระหว่างกัน โจทย์: ตอนนี้ .grid มี grid-template-columns: 1fr 1fr แล้ว แต่ items ยังเบียดชิดกัน เพิ่ม gap: 16px ให้ .grid เพื่อสร้างช่องว่างระหว่าง items ทุกคู่ เงื่อนไข: - ต้องกำหนด gap ที่ .grid - ห้ามแตะ CSS ของ .box ระบบจะตรวจ: 1. .grid มี gap ใน CSS 2. computed row-gap ของ .grid มากกว่า 0 แนวทางการคิด: gap กำหนดที่ parent เสมอ ดูว่า element ไหนคือ container ของ .box
Lab 2: ปรับ gap แยก row กับ column
ชื่อ Lab: ใช้ row-gap และ column-gap แยกกัน เป้าหมาย: กำหนด row-gap: 24px และ column-gap: 12px ให้ .product-grid เพื่อให้ช่องว่างแนวตั้งและแนวนอนต่างกัน โจทย์: .product-grid มีสินค้า 6 ชิ้นอยู่ใน 3 คอลัมน์ ต้องการให้ช่องว่างระหว่างแถว (บนลงล่าง) กว้างกว่าช่องว่างระหว่างคอลัมน์ (ซ้ายขวา) กำหนด row-gap: 24px และ column-gap: 12px ที่ .product-grid เงื่อนไข: - ต้องกำหนด row-gap: 24px ที่ .product-grid - ต้องกำหนด column-gap: 12px ที่ .product-grid - ห้ามใช้ gap shorthand — ต้องแยกเป็น row-gap และ column-gap ระบบจะตรวจ: 1. .product-grid มี row-gap: 24px ใน CSS 2. .product-grid มี column-gap: 12px ใน CSS 3. computed row-gap ของ .product-grid = 24px แนวทางการคิด: ใช้ row-gap แทน gap เมื่อต้องการแยกควบคุมระยะห่างแนวตั้งและแนวนอน
Lab 3: ปรับ card grid ให้มีช่องว่างสม่ำเสมอ
ชื่อ Lab: Card Grid ที่มีช่องว่างสม่ำเสมอ เป้าหมาย: เพิ่ม gap ให้ .card-grid เพื่อให้ card ทุกใบมีช่องว่างสม่ำเสมอ ไม่เบียดกัน โจทย์: .card-grid มี card 6 ใบใน 3 คอลัมน์ แต่ตอนนี้ cards เบียดชิดกัน เพิ่ม gap อย่างน้อย 12px ให้ .card-grid เพื่อให้ cards มีช่องว่างที่พอดี เงื่อนไข: - ต้องกำหนด gap ที่ .card-grid - ค่า gap ต้องอย่างน้อย 12px - ห้ามแก้ HTML หรือ CSS ของ .card ระบบจะตรวจ: 1. .card-grid มีอยู่ใน HTML 2. .card-grid มี gap ใน CSS 3. computed row-gap ของ .card-grid ≥ 12px แนวทางการคิด: เลือกค่า gap ที่ดูสวยงามสำหรับ card grid เช่น 16px หรือ 20px ก็ได้