CSS
Transitions & Animations
hover / active effects
:hover และ :active คือ pseudo-classes ที่ทำให้ CSS เปลี่ยนสไตล์ตามการโต้ตอบของผู้ใช้ — :hover ตอนเมาส์ชี้ :active ตอนกด — ทั้งสองช่วยให้ UI บอกผู้ใช้ว่า element ตอบสนองต่อพวกเขาได้
หัวข้อนี้คืออะไร
:hover และ :active คือ pseudo-classes — selector พิเศษที่ CSS ใช้ตรวจสถานะการโต้ตอบของผู้ใช้กับ element :hover — ทำงานเมื่อเมาส์ชี้อยู่เหนือ element ใช้แสดงว่า "element นี้กดได้นะ" :active — ทำงานเฉพาะขณะที่ผู้ใช้กดปุ่มค้างอยู่ ให้ feedback ทันทีว่า "กำลังกดอยู่" สิ่งที่ทำได้ด้วย :hover และ :active: เปลี่ยน background-color, color, border ใช้ transform เช่น scale หรือ translateY เปลี่ยน box-shadow, opacity สร้าง effect ใดก็ได้ที่ CSS สามารถกำหนดได้ :hover กับ :active ไม่ได้ใช้ได้แค่กับปุ่ม — ใช้ได้กับทุก element เช่น div, a, li, img
- :hover — เมาส์ชี้อยู่เหนือ element ใช้สื่อว่า 'กดได้' หรือ 'interactive'
- :active — ขณะกดปุ่มค้างอยู่ ให้ feedback ทันทีว่า 'กำลังตอบสนอง'
- :focus — (ใกล้เคียง) เมื่อ element รับ keyboard focus เช่น tab หรือคลิก input
- มักใช้ร่วมกับ transition เพื่อให้การเปลี่ยนสถานะดูนุ่มนวล
ทำไมหัวข้อนี้สำคัญ
UI ที่ไม่ตอบสนองเมื่อผู้ใช้ชี้หรือกด รู้สึก "ตาย" และทำให้ผู้ใช้ไม่แน่ใจว่ากด element ถูกต้องหรือเปล่า :hover และ :active ช่วยสร้าง feedback loop ที่สำคัญ: Visual feedback — บอกผู้ใช้ว่า element ตอบสนองต่อพวกเขา Affordance — ช่วยให้รู้ว่าอะไรกดได้ อะไรแค่ดู Confidence — เมื่อเห็น effect เล็กน้อยตอนกด ผู้ใช้รู้ว่า "ทำงานแล้ว" ข้อควรระวังสำคัญ: บนมือถือและ tablet ไม่มี hover state แบบเดียวกับ desktop — เพราะไม่มีเมาส์ที่ "ชี้" อยู่บน element ได้โดยไม่กด ดังนั้นควรออกแบบให้ UI ทำงานได้โดยไม่พึ่ง hover เพียงอย่างเดียว อย่าซ่อนข้อมูลสำคัญไว้ใน hover-only state
ตัวอย่างจากชีวิตจริง
ลองนึกถึงปุ่มลิฟต์: ปุ่มลิฟต์ธรรมดา — กดแล้วไม่มีอะไรเกิดขึ้น ไม่รู้ว่ากดสำเร็จหรือเปล่า ปุ่มลิฟต์ที่ดี — เมื่อกด ไฟจะสว่างขึ้น บอกว่า "รับคำสั่งแล้ว" บน UI จริง: ปุ่ม "สั่งซื้อ" — เมื่อ hover เข้มขึ้นเล็กน้อย บอกว่ากดได้ / เมื่อกด "ยุบ" ลงนิดนึง บอกว่ากำลังตอบสนอง Link ใน nav — เมื่อ hover เปลี่ยนสีและขีดเส้นใต้ บอกว่าคลิกได้ การ์ดสินค้า — เมื่อ hover ยกขึ้นเล็กน้อย บอกว่ากดได้เพื่อดูรายละเอียด ปุ่ม icon — เมื่อ hover วงกลม background ปรากฏขึ้น บอกขอบเขตของ click area
แนวคิดหลักที่ต้องเข้าใจ
ดู :hover และ :active ทำงานอย่างไรบน element ต่างๆ — hover และกดเพื่อดูผล:
| State | Trigger | ใช้ทำอะไร |
|---|---|---|
| :hover | เมาส์อยู่เหนือ element | บอกว่า element interactive กดได้ |
| :active | ขณะกดปุ่มเมาส์ค้างอยู่ | Feedback ทันทีว่ากำลังตอบสนอง |
| :focus | element รับ keyboard focus | Accessibility — tab navigation |
| :focus-visible | focus จาก keyboard เท่านั้น | ไม่แสดง focus ring เมื่อคลิกด้วยเมาส์ |
การทำงานทีละขั้นตอน
วิธีออกแบบ hover / active effect ที่ดีและสื่อความหมาย:
- 1. ถามว่า effect ต้องการสื่ออะไร — 'กดได้' ใช้ hover เปลี่ยนสีหรือยกขึ้น / 'กำลังกด' ใช้ active ยุบลงหรือเข้มขึ้น
- 2. เพิ่ม transition บน element ปกติก่อนเสมอ — เช่น transition: background-color 0.2s ease, transform 0.15s ease
- 3. ให้ hover effect เบาและสื่อความหมาย — เปลี่ยนสี 10–20% หรือ translateY(-2px) พอให้รู้สึก ไม่ต้อง dramatize มาก
- 4. Active effect ควรตรงข้ามกับ hover — ถ้า hover ยกขึ้น active ควรยุบลง เหมือนกดปุ่มจริงๆ
- 5. ทดสอบบนมือถือด้วย — ตรวจว่า UI ยังใช้ได้โดยไม่มี hover state เพราะมือถือไม่มี hover แบบ desktop
ตัวอย่างเชิงเทคนิค — effect พอดีและสื่อความหมาย
ตัวอย่างปุ่ม 3 แบบ: ไม่มี effect / effect มากเกินไป / effect พอดี — ลองแก้โค้ดดู:
จุดที่ผู้เริ่มต้นมักสับสน
- hover ไม่ทำงานบนมือถือ — touch device ไม่มีสถานะ 'เมาส์ชี้อยู่' แบบ desktop อย่าซ่อนฟังก์ชันสำคัญไว้ใน hover-only
- ลืม transition ทำให้ effect กระชาก — .btn:hover { background: blue; } โดยไม่มี transition ทำให้สีเปลี่ยนทันที ควรวาง transition บน .btn ก่อน
- :active ทำงานสั้นมาก — จะเห็นเฉพาะขณะกดค้างอยู่เท่านั้น ถ้า effect นานเกินไปจะไม่เห็น ให้ใช้ transition ที่สั้น หรือไม่มี transition บน :active
- ลำดับ pseudo-class มีผลกับ specificity — ควรเขียน :link, :visited, :hover, :active ตามลำดับ (จำด้วย "LoVe HAte")
เปรียบเทียบ :hover กับ :active และ :focus
| Pseudo-class | เมื่อไหร่ | ใช้ทำอะไรบ่อย | รองรับมือถือ? |
|---|---|---|---|
| :hover | เมาส์ชี้บน element | เปลี่ยนสี, ยกขึ้น, shadow | ไม่มี (เว้นแต่ touch-hover emulation) |
| :active | ขณะกดค้าง | ยุบลง, เข้มขึ้น, scale ลง | ใช่ (touch เป็น active ขณะแตะ) |
| :focus | element รับ focus | outline, ring สำหรับ keyboard nav | ใช่ |
| :focus-visible | focus จาก keyboard เท่านั้น | outline เฉพาะ keyboard ไม่โชว์ตอน click | ใช่ |
สรุปท้ายบทแบบจำง่าย
:hover = "เมาส์ชี้ → บอกว่ากดได้" :active = "กำลังกด → บอกว่าตอบสนองแล้ว" กฎสำคัญ 3 ข้อ:
- ใส่ transition บน element ปกติเสมอ — เพื่อให้ :hover และ :active ดูนุ่มนวล
- Effect พอดี — hover เปลี่ยนแค่พอสังเกตได้ active กลับทิศทางหรือเข้มกว่า hover
- อย่าพึ่ง hover เพียงอย่างเดียว — มือถือไม่มี hover ให้ UI ทำงานได้โดยไม่ต้องใช้ hover
Lab 1 — เพิ่ม hover effect ให้ปุ่ม
โจทย์: .btn ด้านล่างยังไม่มี :hover effect และไม่มี transition เพิ่มให้ครบ: - transition: background-color 0.2s ease, transform 0.15s ease; บน .btn - .btn:hover { background-color: #1d4ed8; transform: translateY(-2px); }
Lab 2 — เพิ่ม active effect
โจทย์: .btn มี :hover อยู่แล้ว แต่ยังไม่มี :active effect เพิ่ม .btn:active ที่ทำให้ปุ่มดู "กด" ลง: - background-color: #1e40af (เข้มกว่า hover) - transform: translateY(1px) (ยุบลงแทนที่จะยกขึ้น) - box-shadow: none
Lab 3 — ปรับ effect ที่มากเกินไปให้พอดี
โจทย์: .btn ด้านล่างมี hover effect ที่มากเกินไปและรบกวนการใช้งาน ปรับให้ effect พอดีและสื่อความหมาย: - hover: เปลี่ยน background-color เป็น #1d4ed8 และ transform: translateY(-2px) เท่านั้น (ลบ scale และ rotate ออก) - transition: ควรใช้ duration ไม่เกิน 0.25s