0Pricing
Tailwind CSS Academy · บทเรียน

แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่

สร้างแถบด้านข้างแบบลิ้นชักที่เลื่อนเข้ามาบนอุปกรณ์เคลื่อนที่ พร้อมตัวสลับ JavaScript ฉากหลังแบบซ้อนทับ และการเปลี่ยนผ่าน translate ที่นุ่มนวล

แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่ เป็นบทเรียน Tailwind CSS Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Tailwind CSS Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Tailwind CSS Academy มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

What Is a Mobile Drawer Sidebar

A mobile drawer sidebar slides in from the left edge of the screen when a hamburger button is tapped, and slides out when dismissed. Unlike a desktop sidebar that is always visible, the mobile drawer is hidden off-screen by default using a CSS transform.

Three elements work together: the backdrop overlay that darkens the rest of the page, the sidebar panel that slides in, and the toggle button in the top bar that opens and closes the drawer.

<!-- Closed state: sidebar off-screen left -->
<aside id="drawer" class="fixed inset-y-0 left-0 w-72 bg-white z-50
                          -translate-x-full transition-transform duration-300">
  <!-- sidebar content -->
</aside>

<!-- Backdrop: hidden until drawer opens -->
<div id="backdrop" class="fixed inset-0 bg-black/50 z-40 hidden"></div>

The Open/Close JavaScript Toggle

The toggle works by removing the -translate-x-full class from the drawer and removing the hidden class from the backdrop. Closing reverses both operations.

A simple helper function openDrawer() and closeDrawer() keeps the logic clean. Add overflow-hidden to the body when the drawer is open to prevent scrolling the page content behind the overlay.

<script>
  const drawer = document.getElementById('drawer');
  const backdrop = document.getElementById('backdrop');

  function openDrawer() {
    drawer.classList.remove('-translate-x-full');
    backdrop.classList.remove('hidden');
    document.body.classList.add('overflow-hidden');
  }

  function closeDrawer() {
    drawer.classList.add('-translate-x-full');
    backdrop.classList.add('hidden');
    document.body.classList.remove('overflow-hidden');
  }

  // Clicking backdrop closes the drawer
  backdrop.addEventListener('click', closeDrawer);
</script>

Slide-In Transition With Tailwind

Tailwind's transition-transform duration-300 on the drawer panel creates a smooth slide animation when -translate-x-full is toggled. The duration-300 sets a 300ms ease transition, which feels snappy but not jarring.

You can customize the easing with ease-in-out and adjust the duration to duration-200 for a faster feel on simpler UIs. The key is that no custom CSS keyframes are needed — Tailwind's transition utilities handle it all.

<!-- Drawer with slide transition -->
<aside
  id="drawer"
  class="fixed inset-y-0 left-0 w-72 bg-gray-900 text-white z-50
         -translate-x-full transition-transform duration-300 ease-in-out
         flex flex-col">
  <!-- Header -->
  <div class="flex items-center justify-between px-5 py-4 border-b border-gray-800">
    <span class="font-bold text-white">Menu</span>
    <button onclick="closeDrawer()" class="text-gray-400 hover:text-white">
      <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
    </button>
  </div>
</aside>

Backdrop Overlay Styling

The backdrop overlay dims the content behind the open drawer, visually communicating that the drawer is a focused panel requiring attention. Use fixed inset-0 bg-black/50 z-40 so it covers the full viewport at a 50% opacity black color.

The backdrop sits at z-40 (below the drawer's z-50) so the drawer renders on top. Adding a fade-in transition with transition-opacity duration-300 makes the overlay appear more naturally.

<div
  id="backdrop"
  class="fixed inset-0 bg-black/50 z-40 hidden
         transition-opacity duration-300">
</div>

Drawer Navigation Links

Inside the drawer, navigation links use the same pattern as the desktop sidebar but can use slightly larger text since this is a touch interface: text-base instead of text-sm for better readability on mobile screens.

Add tap-highlight-color: transparent behavior by using active:bg-gray-800 to give immediate visual feedback when a link is tapped. The list is scrollable using flex-1 overflow-y-auto.

<nav class="flex-1 overflow-y-auto px-4 py-6 space-y-1">
  <a href="/" onclick="closeDrawer()"
     class="flex items-center gap-3 px-3 py-3 rounded-lg text-base font-medium
            bg-gray-800 text-white">
    Home
  </a>
  <a href="/features" onclick="closeDrawer()"
     class="flex items-center gap-3 px-3 py-3 rounded-lg text-base font-medium
            text-gray-300 hover:bg-gray-800 hover:text-white
            active:bg-gray-800 transition-colors">
    Features
  </a>
  <a href="/pricing" onclick="closeDrawer()"
     class="flex items-center gap-3 px-3 py-3 rounded-lg text-base font-medium
            text-gray-300 hover:bg-gray-800 hover:text-white
            active:bg-gray-800 transition-colors">
    Pricing
  </a>
</nav>

Hamburger Button in Top Bar

On mobile, the hamburger button lives in the top bar that replaces the sidebar. Use lg:hidden on this top bar so it only shows on small screens where the sidebar is hidden.

Give the button a comfortable touch target of at least 44×44px by using p-2 with a 24px icon (w-6 h-6), which totals the 44px recommended by Apple's HIG and Google's Material Design guidelines.

<header class="lg:hidden flex items-center justify-between px-4 py-3 bg-white border-b border-gray-200">
  <span class="font-bold text-gray-900">AppDash</span>
  <button
    onclick="openDrawer()"
    aria-label="Open navigation"
    class="p-2 text-gray-600 hover:bg-gray-100 active:bg-gray-200 rounded-lg">
    <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>
</header>

Keyboard Escape to Close

Accessibility requires that overlay elements like drawers can be dismissed with the Escape key. Add a keydown listener to the document that checks for event.key === 'Escape' and calls closeDrawer().

This is a WCAG 2.1 requirement for all modal surfaces. Without Escape support, keyboard-only users are trapped inside the drawer.

<script>
  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape') {
      closeDrawer();
    }
  });
</script>

Right-Side Drawer Variant

Some UIs use a right-side drawer for filters, settings panels, or detail views rather than navigation. Replace left-0 with right-0 and change the closed transform from -translate-x-full to translate-x-full so the panel slides in from the right edge.

This is the same technique used for shopping cart sidebars, notification panels, and detail panes in single-page applications.

<!-- Right drawer -->
<aside
  id="right-drawer"
  class="fixed inset-y-0 right-0 w-80 bg-white shadow-xl z-50
         translate-x-full transition-transform duration-300 ease-in-out
         flex flex-col">
  <div class="flex items-center justify-between px-5 py-4 border-b border-gray-100">
    <h2 class="text-lg font-semibold text-gray-900">Filter Options</h2>
    <button onclick="closeRightDrawer()" class="p-1 text-gray-400 hover:text-gray-600 rounded">
      <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
    </button>
  </div>
  <div class="flex-1 overflow-y-auto p-5">
    <!-- Filter controls go here -->
  </div>
</aside>

Swipe-to-Close Hint Styling

On touch devices, users often expect to be able to swipe the drawer closed. While actual swipe detection requires JavaScript (Touch Events API), you can provide a visual hint by adding a drag handle at the top of the drawer — a short horizontal bar that signals swipeability.

Style it as a small rounded rectangle: mx-auto mt-2 w-10 h-1 rounded-full bg-gray-300. This is a common UX convention from native mobile apps adapted to the web.

<aside class="fixed inset-y-0 left-0 w-72 bg-gray-900 z-50 flex flex-col -translate-x-full transition-transform duration-300">
  <!-- Drag handle -->
  <div class="flex justify-center pt-3">
    <div class="w-10 h-1 rounded-full bg-gray-600"></div>
  </div>
  <!-- Header -->
  <div class="flex items-center justify-between px-5 py-4 mt-1 border-b border-gray-800">
    <span class="font-bold text-white">Menu</span>
    <button onclick="closeDrawer()" class="text-gray-400 hover:text-white">
      &times;
    </button>
  </div>
</aside>

Focus Trap for Accessibility

When the drawer is open, keyboard focus should be trapped inside it. This prevents Tab key navigation from reaching content hidden behind the overlay, which confuses screen reader users.

While implementing a full focus trap requires JavaScript (cycling through focusable elements with Tab and Shift+Tab), always ensure the close button is the first focusable element inside the drawer and receives autofocus or is programmatically focused when the drawer opens.

<script>
  function openDrawer() {
    const drawer = document.getElementById('drawer');
    const backdrop = document.getElementById('backdrop');
    drawer.classList.remove('-translate-x-full');
    backdrop.classList.remove('hidden');
    document.body.classList.add('overflow-hidden');

    // Move focus into drawer for accessibility
    const closeBtn = drawer.querySelector('button[data-close]');
    if (closeBtn) closeBtn.focus();
  }
</script>

<!-- Close button receives focus first -->
<button
  data-close
  onclick="closeDrawer()"
  class="text-gray-400 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white rounded"
  aria-label="Close menu">
  <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
  </svg>
</button>

Complete Drawer Layout Assembly

A complete mobile drawer integrates all the pieces: a top bar with the hamburger button, the off-screen drawer panel with a close button and navigation links, and a backdrop overlay. The three pieces are independent HTML elements that JavaScript connects together.

On desktop (lg: breakpoint), hide the top bar with lg:hidden and show the persistent sidebar instead. This single mobile/desktop split is the foundation of every modern dashboard layout.

<!-- Top bar (mobile only) -->
<header class="lg:hidden sticky top-0 bg-white border-b border-gray-200 z-30 flex items-center justify-between px-4 py-3">
  <span class="font-bold">AppDash</span>
  <button onclick="openDrawer()" aria-label="Open menu" class="p-2 text-gray-600 hover:bg-gray-100 rounded-lg">
    <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>
</header>

<!-- Backdrop -->
<div id="backdrop" class="hidden fixed inset-0 bg-black/50 z-40" onclick="closeDrawer()"></div>

<!-- Drawer panel -->
<aside id="drawer" class="fixed inset-y-0 left-0 w-72 bg-gray-900 text-white z-50 flex flex-col -translate-x-full transition-transform duration-300">
  <div class="flex items-center justify-between px-5 py-4 border-b border-gray-800">
    <span class="font-bold text-white">AppDash</span>
    <button data-close onclick="closeDrawer()" aria-label="Close menu" class="text-gray-400 hover:text-white">&times;</button>
  </div>
  <nav class="flex-1 overflow-y-auto px-4 py-6 space-y-1">
    <a href="/" class="block px-3 py-3 rounded-lg text-base font-medium bg-gray-800 text-white">Home</a>
    <a href="/features" class="block px-3 py-3 rounded-lg text-base font-medium text-gray-300 hover:bg-gray-800 hover:text-white">Features</a>
  </nav>
</aside>

Quick Check

Test your understanding of Tailwind CSS Mastery concepts from this lesson.

Lesson Recap

In this lesson you learned: the mobile drawer uses three elements — backdrop overlay, slide-in panel, and hamburger trigger; the slide animation toggles -translate-x-full with transition-transform duration-300; and accessibility requires Escape-key support, focus management into the drawer on open, and a clickable backdrop to close. Next up we style text inputs and textareas.

คำถามที่พบบ่อย

บทเรียน “แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Tailwind CSS Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Tailwind CSS Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่”

สร้างแถบด้านข้างแบบลิ้นชักที่เลื่อนเข้ามาบนอุปกรณ์เคลื่อนที่ พร้อมตัวสลับ JavaScript ฉากหลังแบบซ้อนทับ และการเปลี่ยนผ่าน translate ที่นุ่มนวล คุณปฏิบัติ Tailwind CSS Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Tailwind CSS Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Tailwind CSS Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Tailwind CSS Academy นี้ได้ไหม

ได้ บทเรียน Tailwind CSS Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างแถบนำทางแบบตอบสนอง
  2. การนำทางแบบติดค้างและตรึงตำแหน่ง
  3. การจัดวางแถบด้านข้างแนวตั้ง
  4. แถบด้านข้างแบบยุบได้บนอุปกรณ์เคลื่อนที่
← กลับไปที่ Tailwind CSS Academy