Skip to content

Drawer

The Drawer component provides a sliding panel that appears from the edge of the screen. It's commonly used for navigation menus, filters, or contextual information that doesn't need to be visible at all times but should be easily accessible.

Basic Usage

html
<button class="button" onclick="document.getElementById('basic-drawer').classList.add('open')">Open Drawer</button>

<div class="drawer-backdrop" id="basic-drawer-backdrop" onclick="document.getElementById('basic-drawer').classList.remove('open')"></div>

<div class="drawer" id="basic-drawer">
  <div class="drawer-header">
    <h3>Drawer Title</h3>
    <button class="drawer-close" onclick="document.getElementById('basic-drawer').classList.remove('open')">×</button>
  </div>
  <div class="drawer-body">
    <p>This is a basic drawer with header, body, and footer.</p>
    <ul class="menu">
      <li><a href="#">Menu Item 1</a></li>
      <li><a href="#">Menu Item 2</a></li>
      <li><a href="#">Menu Item 3</a></li>
    </ul>
  </div>
  <div class="drawer-footer">
    <button class="button" onclick="document.getElementById('basic-drawer').classList.remove('open')">Close</button>
  </div>
</div>

<script>
  // Simple implementation to manage backdrop
  const drawer = document.getElementById('basic-drawer');
  const backdrop = document.getElementById('basic-drawer-backdrop');
  
  drawer.addEventListener('transitionend', () => {
    if (!drawer.classList.contains('open')) {
      backdrop.style.display = 'none';
    }
  });
  
  const openDrawer = () => {
    backdrop.style.display = 'block';
    setTimeout(() => {
      drawer.classList.add('open');
      backdrop.classList.add('visible');
    }, 10);
  };
</script>

Drawer Title

This is a basic drawer with header, body, and footer.

Variants

Position Variants

Drawers can slide in from different edges of the screen.

html
<button class="button" onclick="document.getElementById('left-drawer').classList.add('open')">Left Drawer</button>
<button class="button" onclick="document.getElementById('right-drawer').classList.add('open')">Right Drawer</button>
<button class="button" onclick="document.getElementById('top-drawer').classList.add('open')">Top Drawer</button>
<button class="button" onclick="document.getElementById('bottom-drawer').classList.add('open')">Bottom Drawer</button>

<div class="drawer left" id="left-drawer"><!-- Left drawer (default) --></div>
<div class="drawer right" id="right-drawer"><!-- Right drawer --></div>
<div class="drawer top" id="top-drawer"><!-- Top drawer --></div>
<div class="drawer bottom" id="bottom-drawer"><!-- Bottom drawer --></div>

Left Drawer

This drawer slides in from the left.

Right Drawer

This drawer slides in from the right.

Top Drawer

This drawer slides in from the top.

Bottom Drawer

This drawer slides in from the bottom.

Size Variants

Drawers come in different widths to accommodate various content needs.

html
<div class="drawer sm"><!-- Small drawer --></div>
<div class="drawer"><!-- Medium drawer (default) --></div>
<div class="drawer lg"><!-- Large drawer --></div>
<div class="drawer full"><!-- Full-width/height drawer --></div>

Small Drawer

This is a small drawer.

Medium Drawer

This is a medium drawer (default size).

Large Drawer

This is a large drawer.

Full Drawer

This drawer takes up the full width/height.

Style Variants

Different visual styles for the drawer.

html
<div class="drawer"><!-- Default style --></div>
<div class="drawer bordered"><!-- With prominent border --></div>
<div class="drawer elevated"><!-- With shadow elevation --></div>
<div class="drawer transparent"><!-- With transparent background --></div>

Default Style

This uses the default drawer style.

Bordered Style

This drawer has a more prominent border.

Elevated Style

This drawer has a shadow for elevation.

Transparent Style

This drawer has a transparent background.

Usage Examples

A common use case for drawers is to provide site navigation.

html
<button class="button" onclick="document.getElementById('nav-drawer').classList.add('open')">Menu</button>

<div class="drawer left" id="nav-drawer">
  <div class="drawer-header">
    <h3>Navigation</h3>
    <button class="drawer-close" onclick="document.getElementById('nav-drawer').classList.remove('open')">×</button>
  </div>
  <div class="drawer-body">
    <nav class="menu vertical">
      <li class="menu-item active">
        <a href="#">Home</a>
      </li>
      <li class="menu-item">
        <a href="#">Products</a>
      </li>
      <li class="menu-item">
        <a href="#">Services</a>
      </li>
      <li class="menu-item">
        <a href="#">About</a>
      </li>
      <li class="menu-item">
        <a href="#">Contact</a>
      </li>
    </nav>
  </div>
  <div class="drawer-footer">
    <button class="button sm">Sign In</button>
    <button class="button primary sm">Sign Up</button>
  </div>
</div>

Filter Drawer

Drawers can be used to hold filter controls for a list or grid of items.

html
<button class="button" onclick="document.getElementById('filter-drawer').classList.add('open')">Filters</button>

<div class="drawer right" id="filter-drawer">
  <div class="drawer-header">
    <h3>Filter Products</h3>
    <button class="drawer-close" onclick="document.getElementById('filter-drawer').classList.remove('open')">×</button>
  </div>
  <div class="drawer-body">
    <form>
      <div class="form-group">
        <label for="category">Category</label>
        <select id="category" class="select">
          <option value="">All Categories</option>
          <option value="electronics">Electronics</option>
          <option value="clothing">Clothing</option>
          <option value="books">Books</option>
        </select>
      </div>
      <div class="form-group">
        <label>Price Range</label>
        <div class="range-slider">
          <input type="range" min="0" max="1000" value="500" class="slider" id="price-range">
          <output>$500</output>
        </div>
      </div>
      <div class="form-group">
        <label>Options</label>
        <div class="checkbox">
          <input type="checkbox" id="in-stock" checked>
          <label for="in-stock">In Stock</label>
        </div>
        <div class="checkbox">
          <input type="checkbox" id="on-sale">
          <label for="on-sale">On Sale</label>
        </div>
        <div class="checkbox">
          <input type="checkbox" id="free-shipping">
          <label for="free-shipping">Free Shipping</label>
        </div>
      </div>
    </form>
  </div>
  <div class="drawer-footer">
    <button class="button" onclick="document.getElementById('filter-drawer').classList.remove('open')">Cancel</button>
    <button class="button primary" onclick="document.getElementById('filter-drawer').classList.remove('open')">Apply Filters</button>
  </div>
</div>

Filter Products

$500

Importing

css
/* Required dependencies */
@import '@casoon/ui-lib/core.css';
@import '@casoon/ui-lib/themes/day.css'; /* or another theme */

/* Component modules */
@import '@casoon/ui-lib/ui/components/drawer.css';

CSS Variables

The Drawer component can be customized using CSS variables:

css
:root {
  --drawer-background: var(--color-background);
  --drawer-border: 1px solid var(--color-border);
  --drawer-border-radius: 0;
  --drawer-box-shadow: var(--shadow-lg);
  
  --drawer-width-sm: 240px;
  --drawer-width: 320px;
  --drawer-width-lg: 400px;
  
  --drawer-height-sm: 240px;
  --drawer-height: 320px;
  --drawer-height-lg: 400px;
  
  --drawer-z-index: 1000;
  --drawer-transition-duration: 0.3s;
  --drawer-transition-timing: ease-in-out;
  
  --drawer-header-padding: 1rem 1.5rem;
  --drawer-header-border-bottom: 1px solid var(--color-border);
  --drawer-header-background: var(--color-background);
  
  --drawer-body-padding: 1.5rem;
  --drawer-body-background: var(--color-background);
  
  --drawer-footer-padding: 1rem 1.5rem;
  --drawer-footer-border-top: 1px solid var(--color-border);
  --drawer-footer-background: var(--color-background-100);
  --drawer-footer-gap: 0.5rem;
  
  --drawer-backdrop-background: rgba(0, 0, 0, 0.5);
  --drawer-backdrop-blur: 0;
  --drawer-backdrop-z-index: 999;
}

Available Variables

variableDefaultDescription
--drawer-backgroundvar(--color-background)Background color of the drawer
--drawer-border1px solid var(--color-border)Border of the drawer
--drawer-border-radius0Border radius of the drawer
--drawer-box-shadowvar(--shadow-lg)Box shadow of the drawer
--drawer-width-sm240pxWidth of small drawer
--drawer-width320pxWidth of medium drawer (default)
--drawer-width-lg400pxWidth of large drawer
--drawer-height-sm240pxHeight of small drawer (for top/bottom)
--drawer-height320pxHeight of medium drawer (for top/bottom)
--drawer-height-lg400pxHeight of large drawer (for top/bottom)
--drawer-z-index1000Z-index of the drawer
--drawer-transition-duration0.3sDuration of drawer animations
--drawer-transition-timingease-in-outTiming function for animations
--drawer-header-padding1rem 1.5remPadding of the header
--drawer-header-border-bottom1px solid var(--color-border)Border at the bottom of the header
--drawer-header-backgroundvar(--color-background)Background color of the header
--drawer-body-padding1.5remPadding of the body
--drawer-body-backgroundvar(--color-background)Background color of the body
--drawer-footer-padding1rem 1.5remPadding of the footer
--drawer-footer-border-top1px solid var(--color-border)Border at the top of the footer
--drawer-footer-backgroundvar(--color-background-100)Background color of the footer
--drawer-footer-gap0.5remGap between footer elements
--drawer-backdrop-backgroundrgba(0, 0, 0, 0.5)Background color of the backdrop
--drawer-backdrop-blur0Backdrop blur amount
--drawer-backdrop-z-index999Z-index of the backdrop

Accessibility

The Drawer component is designed with accessibility in mind:

  • Keyboard Navigation:
    • Escape key should close the drawer
    • Tab key should navigate through focusable elements inside the drawer
    • Focus is trapped within the drawer while open
  • Focus Management:
    • When opened, focus should automatically move to the first focusable element in the drawer
    • When closed, focus should return to the element that triggered the drawer
  • ARIA Attributes:
    • role="dialog" indicates the drawer's purpose
    • aria-modal="true" indicates it's a modal element
    • aria-labelledby associates the drawer with its header for screen readers
  • Screen Reader Announcements:
    • Opening and closing of the drawer should be announced to screen readers
  • Motion Reduction:
    • Animations should respect the user's motion preferences via prefers-reduced-motion
html
<!-- Accessible drawer implementation -->
<div class="drawer" id="accessible-drawer" role="dialog" aria-modal="true" aria-labelledby="drawer-title" aria-describedby="drawer-description">
  <div class="drawer-header">
    <h3 id="drawer-title">Drawer Title</h3>
    <button class="drawer-close" aria-label="Close drawer">×</button>
  </div>
  <div class="drawer-body">
    <p id="drawer-description">Drawer content description.</p>
    <!-- Drawer content -->
  </div>
</div>

Browser Compatibility

FeatureChromeFirefoxSafariEdgeIE
Basic functionality⚠️
CSS transitions⚠️
Position fixed
Transform transitions⚠️
Backdrop filter

Legend: ✅ Full support, ⚠️ Partial support, ❌ No support

Note: For IE support, consider using polyfills or alternative implementations for modern CSS features.

Performance Considerations

  • Animation Performance: Use CSS transforms for animations instead of animating width/height properties
  • DOM Size: Be cautious about including large, complex content within drawers
  • Event Handling: Properly manage event listeners to prevent memory leaks
  • Backdrop Blur: Be aware that backdrop blur can cause performance issues on some devices
  • Touch Events: For mobile devices, consider implementing touch gestures for opening/closing drawers
  • Rendering Optimization: Use will-change property judiciously to optimize performance
  • Lazy Loading: Consider lazy loading drawer content if it's complex or data-heavy
  • Dialog - Modal dialog component
  • Modal - Centered modal window
  • Navigation - Site navigation component
  • Sidebar - Permanent sidebar component
  • Menu - Menu component often used inside drawers </rewritten_file>