CSS
Responsive Design
Media queries
media queries ใช้เพิ่มหรือเปลี่ยน CSS ตามเงื่อนไขของอุปกรณ์หรือขนาดหน้าจอ — เป็นกลไกหลักของ responsive design ที่ทำให้หน้าเดียวกันแสดงผลต่างกันบนมือถือและเดสก์ท็อป
หัวข้อนี้คืออะไร
media queries คือ CSS at-rule (@media) ที่ใช้กำหนดเงื่อนไขว่า CSS ชุดไหนจะทำงานเมื่อไหร่ หลักการทำงาน: CSS ปกติทำงานก่อนเสมอ — กำหนด style พื้นฐาน media query จะเพิ่มหรือเปลี่ยนค่า CSS เฉพาะเมื่อเงื่อนไขตรง เช่น หน้าจอกว้างกว่า 768px media queries ไม่ได้แทนที่ CSS ปกติ — เป็นแค่การ "เสริม" ตามบริบท syntax พื้นฐาน:
media query ห่อ CSS ไว้ข้างใน — CSS นั้นจะทำงานเฉพาะเมื่อเงื่อนไขตรงเท่านั้น
/* ทำงานเมื่อหน้าจอกว้างอย่างน้อย 768px */
@media (min-width: 768px) {
.container {
max-width: 960px;
margin: 0 auto;
}
}
/* ทำงานเมื่อหน้าจอกว้างไม่เกิน 600px */
@media (max-width: 600px) {
.sidebar {
display: none;
}
}ทำไมหัวข้อนี้สำคัญ
ผู้ใช้เข้าเว็บจากหลากหลายขนาดหน้าจอ — มือถือ, tablet, laptop, monitor ขนาดใหญ่ — แต่ละขนาดต้องการ layout และ font-size ที่ต่างกัน ถ้าไม่มี media queries: เว็บที่ออกแบบมาสำหรับ desktop จะดูเล็กมากบนมือถือ หรือต้องซูมออกเพื่ออ่าน ข้อความที่พอดีบน desktop อาจเล็กเกินไปบนมือถือ media queries ทำให้: layout ปรับตัวได้ตามขนาดจริงของหน้าจอ ปุ่มและข้อความมีขนาดเหมาะสมในแต่ละอุปกรณ์ navigation สามารถเปลี่ยนจาก horizontal bar เป็น hamburger menu บนมือถือ grid ที่มี 3 คอลัมน์บน desktop ยุบเหลือ 1 คอลัมน์บนมือถือ
ตัวอย่างจากชีวิตจริง
ลองนึกถึงหนังสือพิมพ์: ฉบับกระดาษขนาดใหญ่ — มีหลายคอลัมน์เพราะมีพื้นที่มาก ฉบับ tabloid หรือมือถือ — ลดเหลือ 1–2 คอลัมน์เพราะพื้นที่จำกัด เนื้อหาเหมือนกัน แต่จัดวางต่างกันตามขนาด บน UI จริง: Shopee / Lazada — desktop แสดง 5–6 สินค้าต่อแถว มือถือแสดง 2 สินค้าต่อแถว Wikipedia — desktop มี sidebar สารบัญ มือถือซ่อน sidebar แสดงเฉพาะเนื้อหา GitHub — desktop มี navigation แบบ tab มือถือยุบเป็น dropdown
แนวคิดหลักที่ต้องเข้าใจ
min-width กับ max-width ต่างกันอย่างไร และเมื่อไหรควรใช้แบบไหน:
| Feature | min-width | max-width |
|---|---|---|
| หมายความว่า | กว้างอย่างน้อย X px | กว้างไม่เกิน X px |
| approach | Mobile First — เขียน default สำหรับมือถือ แล้วเสริมสำหรับจอใหญ่ | Desktop First — เขียน default สำหรับ desktop แล้วลดสำหรับมือถือ |
| แนะนำ | ใช่ — เป็น best practice สมัยใหม่ | ได้ แต่ต้อง override มากกว่า |
| ตัวอย่าง | @media (min-width: 768px) { … } | @media (max-width: 767px) { … } |
การทำงานทีละขั้นตอน
วิธีคิดเมื่อต้องการเขียน media query:
- 1. กำหนด CSS พื้นฐานสำหรับมือถือก่อน — เขียน style ที่ใช้ได้บนหน้าจอเล็ก เช่น column เดียว font เหมาะกับมือถือ
- 2. เลือก breakpoint — จุดที่ layout ควรเปลี่ยน เช่น 640px (sm), 768px (md), 1024px (lg)
- 3. ใช้ min-width เพื่อเสริม CSS — CSS ในแต่ละ breakpoint เพิ่มหรือแก้เฉพาะสิ่งที่ต้องการเปลี่ยน ไม่ต้องเขียนใหม่ทั้งหมด
- 4. ทดสอบทุก breakpoint — ลองปรับขนาด browser หรือใช้ DevTools ตรวจว่า layout ถูกต้องทุกช่วง
- 5. อย่า micro-manage ทุก pixel — กำหนด breakpoint ตาม content ว่า layout เริ่มดูไม่ดีตอนไหน ไม่ใช่ตาม device spec
ตัวอย่างที่ 1 — เปลี่ยน font-size และ spacing
ตัวอย่างง่ายที่สุด: ปรับขนาดตัวอักษรและ padding ตามขนาดหน้าจอ — ลองปรับขนาด preview:
ตัวอย่างที่ 2 — เปลี่ยน layout จากแนวตั้งเป็นแนวนอน
layout ที่พบบ่อยที่สุด: column เดียวบนมือถือ หลายคอลัมน์บน desktop:
ตัวอย่างที่ 3 — Card list แบบ responsive
ใกล้เคียงของจริง: grid ของ card ที่ปรับจำนวนคอลัมน์ตามหน้าจอ:
จุดที่ผู้เริ่มต้นมักสับสน
- เขียน max-width แทน min-width — ทำให้ต้อง override ค่าสำหรับจอใหญ่ทั้งหมด แนะนำให้เขียน default สำหรับมือถือแล้วใช้ min-width ขยายขึ้น (Mobile First)
- ลืมเขียน CSS พื้นฐานก่อน — media query เป็นแค่ส่วนเสริม ต้องมี CSS ปกติก่อน มิฉะนั้นหน้าจอขนาดอื่นจะไม่มี style
- breakpoint มีหน่วยผิด — media query ใช้ px ไม่ใช่ em หรือ % ต้องเขียน min-width: 768px ไม่ใช่ min-width: 768
- CSS ใน media query ต้องอยู่ภายใน { } ของ @media เสมอ — ถ้าวางนอก scope หรือปิด } ไม่ครบ media query จะไม่ทำงาน
เปรียบเทียบ min-width กับ max-width approach
สองแนวทางให้ผลเหมือนกัน แต่ที่มาและการจัดการต่างกัน:
| Mobile First (min-width) | Desktop First (max-width) | |
|---|---|---|
| เขียน default สำหรับ | มือถือ — จอเล็ก | Desktop — จอใหญ่ |
| media query เสริมสำหรับ | จอที่ใหญ่ขึ้น | จอที่เล็กลง |
| ตัวอย่าง | @media (min-width: 768px) { … } | @media (max-width: 767px) { … } |
| ข้อดี | ใช้ CSS น้อยกว่า เหมาะกับมือถือ-first world | เข้าใจง่ายถ้าออกแบบ desktop ก่อน |
| แนะนำ | ใช่ — เป็น best practice ปัจจุบัน | ใช้ได้ แต่ต้องระวัง specificity |
สรุปท้ายบทแบบจำง่าย
media query = "CSS ที่ทำงานเฉพาะเมื่อเงื่อนไขตรง" syntax: @media (min-width: Xpx) { /* CSS ที่ใช้เมื่อกว้างกว่า X */ } กฎ 3 ข้อ:
- CSS พื้นฐานก่อนเสมอ — เขียน style สำหรับมือถือก่อน แล้ว media query ค่อยเสริม
- ใช้ min-width ทิศทางเดียว — ง่ายกว่า max-width และเป็น best practice ปัจจุบัน
- breakpoint ตาม content — กำหนด breakpoint ตอน layout เริ่มดูไม่ดี ไม่ใช่ตาม device spec ตายตัว
Lab 1 — เพิ่ม media query พื้นฐาน
โจทย์: .box มี padding: 16px และ font-size: 16px อยู่แล้ว เพิ่ม media query ที่ทำงานเมื่อหน้าจอกว้างอย่างน้อย 600px: - padding: 40px - font-size: 24px
Lab 2 — เปลี่ยน layout ตามขนาดหน้าจอ
โจทย์: .cards มี 3 card อยู่แล้ว แต่ยังแสดงเป็น 1 คอลัมน์เสมอ เพิ่ม media query ที่เปลี่ยน grid-template-columns: - เมื่อกว้างอย่างน้อย 480px → 2 คอลัมน์ - เมื่อกว้างอย่างน้อย 768px → 3 คอลัมน์
Lab 3 — แก้ media query ที่เขียนผิด
โจทย์: โค้ดด้านล่างต้องการให้ .nav เปลี่ยนจาก column เป็น row เมื่อหน้าจอกว้างอย่างน้อย 768px แต่ไม่ทำงาน มีข้อผิดพลาด 2 จุด: 1. ใช้ max-width: 768px แทนที่จะเป็น min-width: 768px (เงื่อนไขกลับด้าน) 2. ลืมระบุหน่วย px — เขียนแค่ 768 ไม่ใช่ 768px