1.0.1 • Public • Published

    App Drawer

    This document is an explainer for a potential browser-provided "App Drawer" component, implemented as a built-in module. App Drawer is delivered as a Custom Element, making it framework-agnostic and easy to integrate into existing applications. It supports the gestures users expect from experience with native mobile platforms, ensures a consistent UX for opening and dismissal, and solves accessibility issues common to web-based drawer implementations. It ships unstyled, and is easily customized via attributes and CSS Custom Properties.

    Sample code

    <app-drawer id="drawer">
        <a href="/">Home</a>
    <script type="module">
      import 'std:app-drawer';
      drawer.addEventListener('close', () => {


    The concept of an "app drawer" is pervasive on the web. Also referred to as "off-canvas navigation" or modal sidebars, these represent an important component of many User Interfaces and often contain an web app's primary navigation.

    There are a multitude of drawer implementations in userland, many of which suffer from usability or performance issues. The inconsistency and unreliability of important UX characteristics like gestures & keyboard support has fractured web users' expectations of the metaphor, demonstrating the need for a browser-provided solution.

    We want to win back the trust of web users by bringing consistency, reliability and performance to drawer UI's.



    By default, any elements placed into <app-drawer> are rendered within the sliding drawer panel. Children can also be placed into other areas using Named Slots:

      <div slot="backdrop">Placed into the backdrop (grayed out) area</div>
      <div slot="header">Placed first in the drawer area</div>
      <div>Any other children are placed into the drawer (after the header)</div>

    CSS Custom Properties

    Styling can be adjusted using the following CSS Custom Properties:

    • --width: the drawer's default width (default: 200px)
    • --max-width: maximum drawer width as a percentage of the viewport (default: 100)
    • --background: background color for the sliding drawer panel (default: #eee)
    • --backdrop: background for the backdrop/shim behind the drawer (default: rgba(0, 0, 0, 0.5))

    Additionally, the drawer exposes some of its state as CSS Custom Properties, which can be used to reactively style the drawer or any element within it:

    • --percent: the current percent visibility/openness of the drawer during a drag gesture
    • --tf-x: the current CSS transform (translateX(xx)) applied to the drawer during a drag gesture


    Custom Element constructor, inheriting from HTMLElement.

    To create an App Drawer instance programmatically:

    const appDrawer = document.createElement('app-drawer');


    Opens or closes the drawer based on its current state.

    If forceState is a Boolean value, the drawer will be opened or closed regardless of its current state.


    Open the drawer if it is currently closed.

    Note: If invoked during a drawer gesture, overrides the end state of the gesture.


    Close the drawer if it is currently open.

    Note: If invoked during a drawer gesture, overrides the end state of the gesture.

    event: toggle(e)

    Fired when the drawer finishes opening or closing. The event includes a .open property with a Boolean indicating the drawer's new state.

    drawer.addEventListener('toggle', e => {
      console.log('Drawer is now ', ? 'open' : 'closed');

    Open issues and questions

    Please see the issue tracker for open issues on the API surface detailed above.


    This feature would be medium-effort, medium-reward.

    • Applications would no longer need to build and ship custom drawer implementations
    • Developers would not need to implement gesture support or platform-specific differences
    • Users of assistive technologies would benefit from a well-known and DOM-controllable interaction model

    Comparison to existing solutions

    There are a number of standalone drawer implementations available on npm that offer comparable functionality:

    (All of the above statistics are as of 2019-02-06.)


    npm i app-drawer

    DownloadsWeekly Downloads






    Unpacked Size

    57 kB

    Total Files


    Last publish


    • developit