Skip to main content

A smooth, accessible drawer component built with CSS and Tailwind CSS. Create sliding off-canvas panels for navigation, filters, and side menus. Supports multiple positions, overlay backdrops, and toggle controls for mobile-friendly, zero-JavaScript sidebar navigation patterns.

Drawer components slide in from the sides of the viewport to reveal hidden navigation, filters, or additional content. Built on the native HTML dialog element with CSS animations, drawers provide a responsive way to manage layouts on mobile and desktop devices. The Frutjam drawer system supports customizable widths, smooth animations, and overlay backgrounds for professional sidebar navigation.

Class Type Description
drawerBaseSlide-in panel built on the native dialog element
drawer-contentModifierInner content area of the drawer
drawer-backdropModifierOverlay behind the drawer
drawer-startModifierSlides in from the left
drawer-endModifierSlides in from the right
drawer-topModifierSlides in from the top
drawer-bottomModifierSlides in from the bottom

Basic Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<button type="button" class="btn btn-sm" onclick="defaultDrawer.show()">Open drawer</button>
<dialog class="drawer" id="defaultDrawer">
  <div class="drawer-content w-full lg:w-56 p-4">
    <ul class="menu">
      <li class="menu-title"><span>Dashboard</span></li>
      <li><a class="menu-item">Overview</a></li>
      <li><a class="menu-item">Analytics</a></li>

      <li class="menu-title mt-4"><span>Management</span></li>
      <li><a class="menu-item">Users</a></li>
      <li><a class="menu-item">Inventory</a></li>
      <li><a class="menu-item">Settings</a></li>
    </ul>
  </div>
  <button type="button" class="drawer-backdrop" onclick="defaultDrawer.close()">Close Drawer via Backdrop</button>
</dialog>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { useDrawer } from 'frutjam/react'

export default function DrawerDemo() {
  const drawer = useDrawer()
  return (
    <>
      <button type="button" className="btn btn-sm" onClick={drawer.open}>Open drawer</button>
      <dialog ref={drawer.ref} className="drawer">
        <div className="drawer-content w-full lg:w-56 p-4">
          <ul className="menu">
            <li className="menu-title"><span>Dashboard</span></li>
            <li><a className="menu-item">Overview</a></li>
            <li><a className="menu-item">Analytics</a></li>

            <li className="menu-title mt-4"><span>Management</span></li>
            <li><a className="menu-item">Users</a></li>
            <li><a className="menu-item">Inventory</a></li>
            <li><a className="menu-item">Settings</a></li>
          </ul>
        </div>
        <button type="button" className="drawer-backdrop" onClick={drawer.close}>Close Drawer via Backdrop</button>
      </dialog>
    </>
  )
}

JS & React Helper

Use createDrawer from frutjam/js or useDrawer from frutjam/react when the trigger lives outside the drawer or you need programmatic control from anywhere in your code.

Controlled via createDrawer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<button class="btn btn-sm" id="helper-open-btn">Open drawer</button>
<dialog class="drawer" id="helper-drawer">
  <div class="drawer-content w-full lg:w-56 p-4">
    <p class="mb-4 text-sm opacity-70">Controlled via <code>createDrawer</code>.</p>
    <button class="btn btn-sm" id="helper-close-btn">Close</button>
  </div>
  <button type="button" class="drawer-backdrop" id="helper-backdrop">Close</button>
</dialog>
<script type="module">
  import { createDrawer } from 'frutjam/js'
  const drawer = createDrawer(document.getElementById('helper-drawer'))
  document.getElementById('helper-open-btn').onclick = () => drawer.open()
  document.getElementById('helper-close-btn').onclick = () => drawer.close()
  document.getElementById('helper-backdrop').onclick = () => drawer.close()
</script>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { useDrawer } from 'frutjam/react'

export default function DrawerDemo() {
  const drawer = useDrawer()
  return (
    <>
      <button className="btn btn-sm" onClick={drawer.open}>Open drawer</button>
      <dialog ref={drawer.ref} className="drawer">
        <div className="drawer-content w-full lg:w-56 p-4">
          <p className="mb-4 text-sm opacity-70">Controlled via useDrawer.</p>
          <button className="btn btn-sm" onClick={drawer.close}>Close</button>
        </div>
        <button type="button" className="drawer-backdrop" onClick={drawer.close}>Close</button>
      </dialog>
    </>
  )
}

Drawer Customization

The .drawer-backdrop provides a clickable background that closes the drawer when clicked outside the drawer, by removing this element by default prevent drawer not close when click outside.

Close on Backdrop Click

Drawer
html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<button type="button" class="btn btn-sm" onclick="closeDrawerOnBackdropClick.show()">Open drawer</button>
<dialog class="drawer" id="closeDrawerOnBackdropClick">
  <div class="drawer-content w-full lg:w-56 p-4">
    <div class="flex justify-between mb-3">
      <strong>Drawer</strong>
      <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="closeDrawerOnBackdropClick.close()">
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 6l-12 12" /><path d="M6 6l12 12" /></svg>
      </button>
    </div>
    <ul class="menu">
      <li class="menu-title"><span>Dashboard</span></li>
      <li><a class="menu-item">Overview</a></li>
      <li><a class="menu-item">Analytics</a></li>
      
      <li class="menu-title mt-4"><span>Management</span></li>
      <li><a class="menu-item">Users</a></li>
      <li><a class="menu-item">Inventory</a></li>
      <li><a class="menu-item">Settings</a></li>
    </ul>
  </div>
  <button type="button" class="drawer-backdrop" onclick="closeDrawerOnBackdropClick.close()">Close Drawer via Backdrop</button>
</dialog>

Prevent Close on Click Outside

Drawer
html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<button type="button" class="btn btn-sm" onclick="preventCloseClickOutsideDrawer.show()">Open drawer</button>
<dialog class="drawer" id="preventCloseClickOutsideDrawer">
  <div class="drawer-content w-full lg:w-56 p-4">
    <div class="flex justify-between mb-3">
      <strong>Drawer</strong>
      <button type="button" class="btn btn-xs btn-square btn-rounded btn-ghost" onclick="preventCloseClickOutsideDrawer.close()">
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 6l-12 12" /><path d="M6 6l12 12" /></svg>
      </button>
    </div>
    <ul class="menu">
      <li class="menu-title"><span>Dashboard</span></li>
      <li><a class="menu-item">Overview</a></li>
      <li><a class="menu-item">Analytics</a></li>
      
      <li class="menu-title mt-4"><span>Management</span></li>
      <li><a class="menu-item">Users</a></li>
      <li><a class="menu-item">Inventory</a></li>
      <li><a class="menu-item">Settings</a></li>
    </ul>
  </div>
</dialog>

Drawer Placements

Left Drawer (Start)

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<button type="button" class="btn btn-sm" onclick="leftDrawer.show()">Open drawer</button>
<dialog class="drawer drawer-start" id="leftDrawer">
  <div class="drawer-content w-full lg:w-56 p-4">
    <ul class="menu">
      <li>
        <div class="menu-title">Dashboard</div>
        <ul>
          <li><a class="menu-item">Overview</a></li>
          <li><a class="menu-item">Analytics</a></li>
        </ul>
      </li>
      <li>
        <div class="menu-title">Management</div>
        <ul>
          <li><a class="menu-item">Users</a></li>
          <li><a class="menu-item">Inventory</a></li>
          <li><a class="menu-item">Settings</a></li>
        </ul>
      </li>
    </ul>
  </div>
  <button type="button" class="drawer-backdrop" onclick="leftDrawer.close()">Close Drawer via Backdrop</button>
</dialog>

Right Drawer (End)

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<button type="button" class="btn btn-sm" onclick="rightDrawer.show()">Open drawer</button>
<dialog class="drawer drawer-end" id="rightDrawer">
  <div class="drawer-content w-full lg:w-56 p-4">
    <ul class="menu w-full">
      <li>
        <div class="menu-title">Dashboard</div>
        <ul>
          <li><a class="menu-item">Overview</a></li>
          <li><a class="menu-item">Analytics</a></li>
        </ul>
      </li>
      <li>
        <div class="menu-title">Management</div>
        <ul>
          <li><a class="menu-item">Users</a></li>
          <li><a class="menu-item">Inventory</a></li>
          <li><a class="menu-item">Settings</a></li>
        </ul>
      </li>
    </ul>
  </div>
  <button type="button" class="drawer-backdrop" onclick="rightDrawer.close()">Close Drawer via Backdrop</button>
</dialog>

Top Drawer

Contact us
html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<button type="button" class="btn btn-sm" onclick="topDrawer.show()">Open drawer</button>
<dialog class="drawer drawer-top" id="topDrawer">
  <div class="drawer-content p-4">
    <div class="heading-3xl mb-3">Contact us</div>
    <form class="grid grid-cols-12 gap-3">
      <input type="text" placeholder="Enter your text here" class="input col-span-5">
      <input type="text" placeholder="Enter your text here" class="input col-span-5">
      <button class="btn col-span-2">Submit</button>
    </form>
  </div>
  <button type="button" class="drawer-backdrop" onclick="topDrawer.close()">Close Drawer via Backdrop</button>
</dialog>

Bottom Drawer

html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<button type="button" class="btn btn-sm" onclick="bottomDrawer.show()">Open drawer</button>
<dialog class="drawer drawer-bottom" id="bottomDrawer">
  <div class="drawer-content p-4">
    <ul class="menu menu-md w-full">
      <li>
        <div class="accordion accordion-flush">
          <details name="nav" open>
            <summary><span class="heading-md">Dashboard</span></summary>
            <div class="accordion-content">
              <ul>
                <li class="menu-item"><span>Overview</span></li>
                <li class="menu-item">
                  <span>Analytics</span>
                  <div class="badge badge-xs badge-accent ml-1 uppercase">Live</div>
                </li>
              </ul>
            </div>
          </details>

          <details name="nav">
            <summary><span class="heading-md">Settings</span></summary>
            <div class="accordion-content">
              <ul>
                <li class="menu-item"><span>Profile</span></li>
                <li class="menu-item"><span>Security</span></li>
              </ul>
            </div>
          </details>
        </div>
      </li>
    </ul>
  </div>
  <button type="button" class="drawer-backdrop" onclick="bottomDrawer.close()">Close Drawer viaBackdrop</button>
</dialog>