webdevpuneet.com

Side Drawer — Free HTML CSS JS Slide Panel Snippet

Side Drawer · Navigation · Plain HTML, CSS & JS · Live preview

CategoryNavigation

Copy & paste

Source Code

<div class="page">
  <button class="open-btn" onclick="openDrawer()">
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
    Open Drawer
  </button>
</div>

<div class="overlay" id="overlay" onclick="closeDrawer()"></div>

<aside class="drawer" id="drawer">
  <div class="drawer-header">
    <div class="brand">⬡ Acme</div>
    <button class="close-btn" onclick="closeDrawer()">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
    </button>
  </div>
  <nav class="drawer-nav">
    <a href="#" class="nav-item active"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>Dashboard</a>
    <a href="#" class="nav-item"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>Users<span class="badge">12</span></a>
    <a href="#" class="nav-item"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>Billing</a>
    <a href="#" class="nav-item"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>Analytics</a>
    <div class="nav-section">Settings</div>
    <a href="#" class="nav-item"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M4.93 4.93a10 10 0 0 0 0 14.14"/></svg>Preferences</a>
    <a href="#" class="nav-item"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>Sign out</a>
  </nav>
  <div class="drawer-footer">
    <div class="user-pill">
      <div class="user-av">PS</div>
      <div><div class="user-name">Puneet Sharma</div><div class="user-role">Admin</div></div>
    </div>
  </div>
</aside>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

position: fixed; right: 0 — drawer anchored to viewport right edge
translateX(100%) default — drawer hidden off right edge
.open class: translateX(0) — smooth 0.3s ease slide-in
Overlay: fixed full-screen semi-transparent backdrop with opacity transition
.show on overlay adds visibility; removes it on close
Three close: X button, overlay click, ESC keydown — all call closeDrawer()
pointer-events: none on closed overlay — no invisible click blocking
Export as HTML file, React JSX, or React + Tailwind CSS
Mobile (375px), Tablet (768px), Desktop device preview buttons
Live split-pane editor — preview updates as you type

About this UI Snippet

Side Drawer — translateX Slide-In, Overlay Backdrop & Three Close Mechanisms

Screenshot of the Side Drawer snippet rendered live

A side drawer (also called a slide-over or off-canvas panel) slides in from the edge of the screen to show secondary content — filters, settings, navigation, or form details — without navigating away from the current page. Used in mobile navigation, filter panels, and settings sheets — see also the dual nav-and-settings drawer.

The slide-in animation

The drawer has position: fixed; right: 0; top: 0; bottom: 0; transform: translateX(100%) by default — positioned off the right edge of the screen. Adding .open transitions to translateX(0) with transition: transform 0.3s ease. This slides the drawer in from the right.

Three close mechanisms

The X button calls closeDrawer(). The overlay background has onclick="closeDrawer()". A keydown listener closes on Escape. All three call the same function that removes .open from the drawer and .show from the overlay.

The overlay

The overlay is a fixed full-screen div with a semi-transparent background. It shows behind the drawer and blocks interaction with the main content. The opacity transition (0 to 0.5) creates the dimming effect.

The translateX slide animation

Left drawers start at transform: translateX(-100%) — fully off-screen to the left. Adding .open transitions to translateX(0). The cubic-bezier spring curve (fast start, slow settle) creates the feel of a native mobile sheet opening. The CSS transition handles both open and close — removing .open reverses the animation automatically.

Backdrop and z-index layering

The backdrop is position: fixed; inset: 0 with a z-index below the drawer. When .open is applied, the backdrop fades in with opacity and gains pointer-events: all so clicks on it close the drawer. This click-backdrop-to-close is expected behaviour on all mobile UIs.

Push vs overlay mode

This snippet implements overlay mode — the drawer slides over the content with a backdrop. For push mode (content shifts right when drawer opens), add transition: margin-left 0.3s to the main content and set margin-left: 280px when the drawer opens. Overlay communicates temporary context; push communicates a persistent workspace panel.

Focus management for accessibility

When the drawer opens, move focus to the first focusable element inside: drawer.querySelector('a, button, input').focus(). On close, return focus to the element that triggered the open. This prevents keyboard users from losing their position on the page behind the drawer.

The translateX slide animation

Left drawers start at transform: translateX(-100%) — fully off-screen to the left. Adding .open transitions to translateX(0). The cubic-bezier spring curve (fast start, slow settle) creates the feel of a native mobile sheet opening. The CSS transition handles both open and close — removing .open reverses the animation automatically.

Backdrop and z-index layering

The backdrop is position: fixed; inset: 0 with a z-index below the drawer. When .open is applied, the backdrop fades in with opacity and gains pointer-events: all so clicks on it close the drawer. This click-backdrop-to-close is expected behaviour on all mobile UIs.

Push vs overlay mode

This snippet implements overlay mode — the drawer slides over the content with a backdrop. For push mode (content shifts right when drawer opens), add transition: margin-left 0.3s to the main content and set margin-left: 280px when the drawer opens. Overlay communicates temporary context; push communicates a persistent workspace panel.

Focus management for accessibility

When the drawer opens, move focus to the first focusable element inside: drawer.querySelector('a, button, input').focus(). On close, return focus to the element that triggered the open. This prevents keyboard users from losing their position on the page behind the drawer.

Step by step

How to Use

  1. 1
    Click Open drawerClick the button to slide the drawer in from the right. Click the overlay, the × button, or press ESC to close.
  2. 2
    Update drawer contentIn the HTML panel, change the drawer heading, description, and any form fields or links inside.
  3. 3
    Change drawer widthUpdate width: 320px on .drawer in the CSS panel.
  4. 4
    Change slide directionChange translateX(100%) to translateX(-100%) for a left-side drawer, and update right: 0 to left: 0.
  5. 5
    Connect close to form submissionCall closeDrawer() after a successful form submit or action completion.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Settings and preferences panels
Slide in a settings sheet from the right without navigating away. Close returns the user to their previous state.
Detail and edit panels
Show record details or an edit form in a drawer when clicking a table row. The drawer sits over the table without navigating away.
Mobile navigation drawer
Trigger from a hamburger button on mobile. The drawer slides in from the right with nav links and user account options.
Search and filter panels
A filter drawer that slides in from the right on mobile where a sidebar filter panel would not fit.
Learn translateX slide and overlay patterns
The drawer uses translateX(100%) to hide off-screen and translateX(0) to reveal. Edit the transition timing and overlay opacity in the CSS panel.
Shopping cart drawer
Classic e-commerce pattern: clicking a cart icon slides in a cart summary drawer from the right with items, totals, and a checkout button.
Related: View Transitions API Page Navigation
See the View Transitions API Page Navigation for a related navigation pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The drawer has position: fixed; right: 0; transform: translateX(100%) by default — positioned at the right edge but shifted 100% of its own width off-screen. Adding .open transitions to translateX(0) with transition: transform 0.3s ease.

Change right: 0 to left: 0 on .drawer. Change translateX(100%) to translateX(-100%). Change the transform-origin if needed. Everything else is identical.

In openDrawer(), add document.body.style.overflow = "hidden". In closeDrawer(), restore it: document.body.style.overflow = "".

On openDrawer(), get all focusable elements in the drawer: const focusable = drawer.querySelectorAll("button, input, a"). Focus the first one. Add a keydown Tab handler that cycles within the drawer.

Yes. Click "JSX" for a React component. Manage isOpen in useState. Apply the CSS class conditionally: className={isOpen ? "drawer open" : "drawer"}. Use useEffect to add/remove the ESC keydown listener.

Add a CSS animation to the drawer content that triggers when .open is applied: .drawer.open .drawer-content { animation: slideUp 0.3s ease 0.1s both }. The 0.1s delay starts the content animation after the drawer begins sliding in.

Yes. While the Side Drawer snippet gives you one pattern to copy, the free Responsive Navbar Builder at webdevpuneet.com/navbar-builder/ designs a whole navigation bar: logo, links and dropdown menus, a mobile hamburger menu (dropdown panel, slide-in drawer or full screen) and a scroll effect (sticky, shrink, hide on scroll or transparent). It has six presets, a live preview that runs the real code, and exports HTML + CSS + vanilla JS, React, Tailwind, Vue 3 or Angular — or you can click Fork & Edit to keep editing it in My Code.