접을 수 있는 모바일 사이드바
JavaScript 토글, 오버레이 배경, 부드러운 translate 전환을 사용하는 모바일용 슬라이드 인 서랍 사이드바를 구현합니다.
접을 수 있는 모바일 사이드바은(는) CoddyKit의 무료 Tailwind CSS Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 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">
×
</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">×</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 튜터와 함께 HTML을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 30
- 레슨
- 120
자주 묻는 질문
“접을 수 있는 모바일 사이드바” 강의는 무료인가요?
네 — “접을 수 있는 모바일 사이드바” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Tailwind CSS Academy 강의 전체를 잠금 해제할 수 있습니다. Tailwind CSS Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“접을 수 있는 모바일 사이드바”에서 뭘 배우나요?
JavaScript 토글, 오버레이 배경, 부드러운 translate 전환을 사용하는 모바일용 슬라이드 인 서랍 사이드바를 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Tailwind CSS Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Tailwind CSS Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Tailwind CSS Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“접을 수 있는 모바일 사이드바” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Tailwind CSS Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Tailwind CSS Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 반응형 내비게이션 바 만들기
- 고정 및 스티키 내비게이션
- 세로 사이드바 레이아웃
- 접을 수 있는 모바일 사이드바