สร้าง Side Navigation ที่ขยายออกมาเมื่อ hover ด้วย CSS เพียงอย่างเดียว (ไม่ต้อง JavaScript)
ตัวอย่างโค้ด
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> nav a { position: fixed; left: -120px; transition: 0.3s; padding: 10px; width: 140px; text-decoration: none; font-size: 20px; color: black; font-weight: bolder; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } nav a:hover { left: 0; } #Info{ top: 20px; background-color: #6de2f7; } #Social{ top: 80px; background-color: #71fc71; } #Address { top: 140px; background-color: #c4f553; } #Home { top: 200px; background-color: rgb(225, 115, 240); } </style> </head> <body> <nav> <a href="#" id="Home">Home</a> This will produce the following output: On hovering on any one of them they will expland as follows: <a href="#" id="Address">Address</a> <a href="#" id="Social">Social Links</a> <a href="#" id="Info">More Info</a> </nav> </body> </html>
คำอธิบาย
หลักการ: ตั้ง position: fixed และ left: -120px ซ่อนส่วนใหญ่ไว้ข้างนอกจอ แล้ว transition: 0.3s เมื่อ :hover ตั้ง left: 0 ทำให้เลื่อนเข้ามา
โครงสร้าง HTML ที่ถูกต้อง (Fixed):
<nav> <a href="#" id="Home">Home</a> <a href="#" id="Address">Address</a> <a href="#" id="Social">Social Links</a> <a href="#" id="Info">More Info</a> </nav>
ข้อจำกัดของ CSS-only Hover Sidenav:
- Mobile/Touch: ไม่มี hover บน touch screen → ไม่ทำงาน
- Accessibility: Keyboard user ไม่สามารถเข้าถึงได้ (ไม่ได้ focus)
- Content overlap: เมนูทับเนื้อหาเมื่อขยาย
- Accidental trigger: hover ผิดพลาดง่าย
แนวทางแก้ไข (Production Ready):
- ใช้ JavaScript toggle แทน hover (คลิกเพื่อเปิด/ปิด)
- เพิ่ม focus states สำหรับ keyboard navigation
- ใช้ checkbox hack สำหรับ CSS-only ที่รองรับ click
- Media query แสดงปกติบน desktop, hamburger บน mobile
Checkbox Hack Version (CSS-only, Clickable):
<input type="checkbox" id="nav-toggle" hidden>
<label for="nav-toggle" class="hamburger">☰</label>
<nav class="sidenav">...</nav>
#nav-toggle:checked ~ .sidenav { left: 0; }