Drawer

Drawer

The Drawer component is an off-screen content container that slides in from the right when needed. Similar to a modal it provides a focused panel, in this case for the user to open additional controls or filters.

Default drawer

To set up a drawer, create an element with class .hc-drawer. Inside, add a checkbox with class .hc-drawer-toggle and then an element with class .hc-drawer-content that contains the content of the drawer.

This default drawer will fill whatever block-level element it’s inside of and will not have a fixed position to it by default. You can modify this later.

This is where all of the main content goes.

This is the right side drawer.

Note that by default, the content behind the drawer is not accessible while the drawer is open. This can be modified with a class.


<div class="w-full h-full flex flex-col items-center justify-center gap-4">
  <p>
    This is where all of the main content goes.
  </p>
  <label class="hc-button hc-button--primary cursor-pointer" for="drawer_basic" role="button" tabindex="0">
    Open a basic drawer
  </label>
</div>
<div class="hc-drawer">
  <input id="drawer_basic" type="checkbox" class="hc-drawer-toggle" />
  <div class="hc-drawer-content">
    <div class="hc-drawer-content-body">
      <p class="hc-body">
        This is the right side drawer.
      </p>
      <p class="hc-body">
        Note that by default, the content behind the drawer is not accessible while the drawer is open. This can be modified with a class.
      </p>
      <label class="hc-button hc-button--primary cursor-pointer" for="drawer_basic">
        Close the drawer
      </label>
    </div>
  </div>
</div>

No matter where it is or how it’s used, the drawer itself must be inside of an element that has position: relative applied to it.

Label used to toggle the drawer

Toggling the drawer is handled by a <label> that has a corresponding for value for the checkbox inside the drawer. This is the default non-JS method of toggling a drawer but you’re free to use any accessible method to do this, JS or not.

Accessibility note

If using the documented label method, in order for the label (acting as a button) to receive a focus state, add role="button" and tabindex="0" to it.

App drawers

To create a drawer that fills the entire content panel inside of an app and has a fixed position, place the .hc-drawer element at the end of the .hc-app-main container if you’re using the Layout framework. You can also give the drawer the class .hc-drawer--in-main if it needs to sit outside of this element or if you’re not using that framework.

You can use the <aside> element for this. If you do, add the attribute aria-label="Right drawer" or some other more descriptive label for what the drawer contains.

Take a look at the full page layout demo to see this live.

Allow access to background content

By default, the content that sits behind the drawer (i.e., the main page content/scrollable area) will not be accessible to the user while the drawer is open.

To prevent this default, append the class .hc-drawer--allow-bg to the drawer parent element and the user will be able to interact with the main page content.

Mobile handling

Drawers slide in from the right and take up 1/3 of the screen width, with a minimum width of 24rem.

On small screens (up to the md breakpoint) the drawer will instead pull up from the bottom of the screen. This is handled by default and will also occur if you’re using the Layout’s grid container on main content sections that are smaller than 512px.

Test this drawer out when this content window is less than 32rem wide.

Mobile drawer example

On small screens this will slide up from the bottom.

On larger screens this will slide in from the right.

Adding a ton of breaks here to see what happens when the content is forced to scroll.













<div class="w-full h-full flex flex-col items-center justify-center gap-4">
  <p class="text-center">
    Test this drawer out when this content window is less than 32rem wide.
  </p>
  <label class="hc-button hc-button--primary cursor-pointer" for="drawer_mobile" role="button" tabindex="0">
    Open a basic drawer
  </label>
</div>
<div class="hc-drawer">
  <input id="drawer_mobile" type="checkbox" class="hc-drawer-toggle" />
  <div class="hc-drawer-content">
    <div class="hc-drawer-content-title">
      <h3 class="hc-h3">
        Mobile drawer example
      </h3>
      <label class="hc-button hc-button--primary cursor-pointer" aria-label="Close drawer" for="drawer_mobile">
        <i class="hc-icon hc-icon--close hc-icon--20"></i>
      </label>
    </div>
    <div class="hc-drawer-content-body">
      <p class="hc-body">
        On small screens this will slide up from the bottom.
      </p>
      <p class="hc-body">
        On larger screens this will slide in from the right.
      </p>
      <p class="hc-body">
        Adding a ton of breaks here to see what happens when the content is forced to scroll.
        <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
      </p>
    </div>
  </div>
</div>