Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> CSS

การสร้าง Animated Closable Side Navigation Menu ด้วย CSS และ JavaScript

สร้าง Side Navigation Menu ที่ slide เข้ามา (animated) และปิดได้ (closable) ด้วย CSS Transition และ 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> .sideNav {    height: 100vh;    width: 0;    position: fixed;    z-index: 1;    top: 0;    left: 0;    background-color: rgb(46, 218, 195);    overflow-x: hidden;    padding-top: 60px;    transition: 0.5s; } .sideNav a {    padding: 8px 8px 8px 32px;    text-decoration: none;    font-size: 25px;    color: #000000;    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;    display: block;    transition: 0.3s; } .sidenav a:hover {    color: #f1f1f1; } .sideNav .closeBtn {    position: absolute;    top: 0;    right: 25px;    font-size: 36px;    margin-left: 50px; } button {    padding: 15px;    background-color: rgb(0, 27, 145);    color: rgb(255, 255, 255);    font-size: 20px;    border: none;    border-radius: 2%; } </style> </head> <body> <nav class="sideNav"> <a href="#" class="closeBtn">×</a> <a href="#">Login</a> <a href="#">Register</a> <a href="#">Home</a> <a href="#">About Us</a> </nav> <button class="openSideNav">Click here to open sideNav</button> <script>    let openBtn = document.querySelector(".openSideNav");    openBtn.addEventListener("click", () => {       showNav();    });    let closeBtn = document.querySelector(".closeBtn");    closeBtn.addEventListener("click", () => {       hideNav();    });    function showNav() {       document.querySelector(".sideNav").style.width = "300px";    }    function hideNav() {       document.querySelector(".sideNav").style.width = "0";    } </script> </body> </html>

คำอธิบายการทำงาน

  1. CSS: .sideNav เริ่มต้น width: 0 ซ่อนไว้ transition: 0.5s สำหรับ animation
  2. Open: คลิกปุ่ม → JS ตั้ง width: 300px → CSS transition slide เข้ามา
  3. Close: คลิก × (closeBtn) → JS ตั้ง width: 0 → CSS transition slide ออก
  4. Links: transition: 0.3s สำหรับ hover effect

จุดแก้ไขในโค้ดต้นฉบับ (Typo Fix):

  • .sidenav a:hover → ควรเป็น .sideNav a:hover (ตัวใหญ่ N)
  • margin-left: 50px บน closeBtn ควรใช้ right: 25px อย่างเดียวพอ

เวอร์ชันปรับปรุง (Modern & Accessible):

HTML:

<button class="nav-toggle" aria-expanded="false" aria-controls="sidenav" aria-label="Open menu">☰</button>
<nav id="sidenav" class="sidenav" role="dialog" aria-modal="true" aria-label="Navigation">
  <button class="close-btn" aria-label="Close menu">×</button>
  <a href="#">Login</a> ... </nav>
<div class="overlay" hidden></div>

CSS:

.sidenav {
  position: fixed; top: 0; left: 0; height: 100vh; width: 300px;
  transform: translateX(-100%); transition: transform 0.3s ease;
  background: white; z-index: 1000; padding-top: 60px;
}
.sidenav.open { transform: translateX(0); }
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 999; }
.overlay.hidden { display: none; }

JS:

const toggle = document.querySelector('.nav-toggle');
const sidenav = document.querySelector('.sidenav');
const overlay = document.querySelector('.overlay');

toggle.addEventListener('click', () => {
  const open = sidenav.classList.toggle('open');
  toggle.setAttribute('aria-expanded', open);
  overlay.hidden = !open;
});

overlay.addEventListener('click', () => {
  sidenav.classList.remove('open');
  toggle.setAttribute('aria-expanded', 'false');
  overlay.hidden = true;
});

// ESC key to close
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape' && sidenav.classList.contains('open')) {
    sidenav.classList.remove('open');
    toggle.setAttribute('aria-expanded', 'false');
    overlay.hidden = true;
  }
});

ข้อดีของเวอร์ชันปรับปรุง:

  • ใช้ transform: translateX แทน width (performance ดีกว่า, ไม่ทำ reflow)
  • มี Overlay backdrop (คลิกนอกพื้นที่ปิดได้)
  • รองรับ ESC key
  • Accessible (ARIA attributes, focus management)
  • ใช้ class toggle แทน inline style