Black Friday: 50% off all products for the first 50 customers. Only 10 left. Use code
40/50 claimed
See pricing →
November 7, 2026

Quasar Drawer: Mini Mode, Overlay and Breakpoints

Quasar drawer recipes for 2.35.2: a mini rail that expands on hover, overlay on mobile, a right-side panel, custom breakpoints and a remembered open state.
Quasar
Vue
Layout
Navigation

The Quasar drawer (q-drawer) is the sidebar of a q-layout, and most of its behavior comes from one number: the breakpoint. Above it, the drawer sits next to the page. At or below it, the drawer slides over the page with a backdrop. This post covers the parts the basic setup leaves out: a mini rail that expands on hover, overlay mode, a right-side panel, picking the breakpoint, and remembering the user's choice across reloads. Everything is checked against Quasar 2.35.2.

If you haven't set up q-layout, q-header and q-page-container yet, start with the Quasar layout system guide. This post assumes a working layout and goes deeper on the drawer itself.

How the Quasar drawer picks desktop or mobile behavior

QDrawer runs in one of two behaviors, and several props mean different things in each:

Desktop behaviorMobile behavior
Takes space in the layoutYes, unless overlay is setNever
BackdropNoneShown while the drawer is open
Swipe gesturesNoneSwipe to open and close
Body scrollUntouchedLocked while open
miniAppliesIgnored

The breakpoint prop decides which one you get. Its default is 1023, and the drawer is in mobile behavior while the layout width is smaller than or equal to it. That is the layout's width, which for a normal layout is the window width. For a container layout, it's the container's width.

To skip the switch entirely, set behavior="desktop" or behavior="mobile". A drawer with behavior="mobile" always slides over the page, whatever the screen size.

show-if-above and the v-model

show-if-above shows the drawer whenever it's in desktop behavior, even when its v-model starts as false, and it sets the model back to true on first render. When the window shrinks below the breakpoint, the drawer hides and Quasar remembers whether it was open. When the window grows again, the drawer comes back. Without show-if-above, a drawer the user never opened stays closed on desktop too.

This is why the toggle button usually looks like this:

<q-btn flat round dense icon="menu" aria-label="Toggle menu" @click="open = !open" />
<q-drawer v-model="open" show-if-above bordered :width="260">
  <!-- menu -->
</q-drawer>

One button works for both behaviors. On desktop it hides and shows the sidebar. On a phone it opens the slide-over.

Mini mode: an icon rail that expands on hover

Mini mode shrinks the drawer to a rail of icons. The mini prop switches it on, and mini-width sets the rail width (57px by default). Remember that mini is ignored in mobile behavior, so phones still get the full drawer as a slide-over.

<script setup lang="ts">
import { ref } from 'vue'

const open = ref(false)
const mini = ref(true)

const links = [
  { label: 'Inbox', icon: 'inbox', to: '/inbox' },
  { label: 'Reports', icon: 'bar_chart', to: '/reports' },
  { label: 'Settings', icon: 'settings', to: '/settings' },
]
</script>

<template>
  <q-drawer
    v-model="open"
    show-if-above
    bordered
    :width="240"
    :mini="mini"
    mini-to-overlay
    aria-label="Main menu"
    @mouseenter="mini = false"
    @mouseleave="mini = true"
  >
    <nav aria-label="Main">
      <q-list padding>
        <q-item v-for="link in links" :key="link.to" :to="link.to" clickable v-ripple>
          <q-item-section avatar>
            <q-icon :name="link.icon" />
          </q-item-section>
          <q-item-section>{{ link.label }}</q-item-section>
        </q-item>
      </q-list>
    </nav>
  </q-drawer>
</template>

What each piece does:

  • @mouseenter and @mouseleave toggle mini, so the rail opens when the pointer moves onto it. This is the same pattern the Quasar docs use.
  • mini-to-overlay makes the expanded drawer float over the page, while the layout only reserves the rail's width. Without it, the page content shifts sideways on every hover, which feels jumpy.
  • In mini mode, Quasar's CSS hides each q-item's label and main section, so only the avatar icons stay.

For finer control, two CSS classes help: q-mini-drawer-hide hides an element in mini mode (and in mobile behavior), and q-mini-drawer-only shows an element only in mini mode. If the rail needs different markup altogether, the #mini slot replaces the default content while the drawer is mini. And no-mini-animation (since 2.12) turns off the width transition.

Hover doesn't exist on touch screens or for keyboard users, so give the rail a click path too. A chevron button with q-mini-drawer-hide that sets mini = true, plus a click on the rail that sets mini = false, covers both. The Quasar docs show this as the "click trigger" example, using @click.capture so the first click only expands the rail.

Overlay mode

overlay keeps the drawer from taking space even on desktop: it floats over the page instead of pushing the content aside. Quasar puts an overlay drawer in fixed position, whatever the layout's view string says.

Overlay suits drawers the user opens for a moment and closes again, like a filter panel on a data page:

<q-drawer v-model="filtersOpen" side="right" overlay bordered elevated :width="320">
  <q-toolbar>
    <q-toolbar-title>Filters</q-toolbar-title>
    <q-btn flat round dense icon="close" aria-label="Close filters" @click="filtersOpen = false" />
  </q-toolbar>
  <!-- filter fields -->
</q-drawer>

Persistent drawers

While a drawer is dismissible (in mobile behavior, or open as an overlay), it closes itself in three ways besides your v-model: the Escape key, a route change, and the Cordova or Capacitor back button. persistent turns off all three.

It does not stop a backdrop click or a swipe from closing the drawer. For a drawer that only your code can close, add no-swipe-close and no-swipe-backdrop as well.

Right-side drawers

A layout holds one drawer per side. side="right" attaches the second one, and it takes its own breakpoint, width and behavior:

<q-layout view="hHh LpR lFf">
  <q-header bordered>...</q-header>

  <q-drawer v-model="nav" show-if-above bordered :width="240">
    <!-- navigation -->
  </q-drawer>

  <q-drawer v-model="details" side="right" bordered :width="360" :breakpoint="1279">
    <!-- details of the selected row -->
  </q-drawer>

  <q-page-container>
    <router-view />
  </q-page-container>
</q-layout>

The right drawer has no show-if-above, so it opens only when your code sets details to true, for example when the user clicks a table row. Its larger breakpoint makes it slide over the page on laptop-sized screens, where a 360px column would squeeze the table.

One rule to know: in mobile behavior, the two drawers can't be open at the same time. Each one covers the page with its own backdrop, so opening one closes the other and sets its v-model to false. In desktop behavior, both can be open.

If what you actually want on small screens is a full-width menu that drops down from the header rather than a sidebar, that is a different pattern. The Navigation Drawers Block has two of those, built with q-menu under a q-toolbar.

Choosing the breakpoint

The default of 1023 is the top of Quasar's sm screen range, so the drawer docks from 1024px (md) up. Change it when the sidebar and the page fight for space:

  • A wide drawer (300px or more) next to a dense page: raise it to 1439, so the drawer docks only from Quasar's lg size up.
  • A narrow drawer or a mini rail: lower it to 767, so tablets in landscape keep the sidebar.

Because breakpoint is a plain number, you can tie it to Quasar's screen sizes if you prefer names: $q.screen.sizes.lg - 1 (1439) with $q from useQuasar().

Remembering the open state

Users who collapse the sidebar expect it to stay collapsed after a reload. Store the preference, not the v-model. With show-if-above, the drawer's model is overwritten on first render anyway, so the useful thing to save is mini.

In a Quasar CLI single-page app, localStorage is enough:

import { ref, watch } from 'vue'

const mini = ref(localStorage.getItem('drawer-mini') === 'true')
watch(mini, (value) => localStorage.setItem('drawer-mini', String(value)))

With server-side rendering (Nuxt, or Quasar CLI in SSR mode), the server can't read localStorage, so the first render would show the full drawer and then snap to the rail. A cookie avoids the flash, because the server sees it. In Nuxt, useCookie is SSR-friendly and its ref writes the cookie when you change it:

const mini = useCookie<boolean>('drawer-mini', {
  default: () => false,
  maxAge: 60 * 60 * 24 * 365,
})

Bind it with :mini="mini" and a toggle button that flips mini.value. If you use the hover pattern above, save only the click toggle, not every hover.

Accessibility notes

Since 2.25, QDrawer renders a real <aside> element, so screen readers announce it as a complementary landmark. An aria-label on q-drawer lands on that <aside>, which helps when a page has two drawers. Wrap the menu itself in a <nav> with its own label, as in the mini example. A closed drawer leaves the Tab order completely.

Two things stay your job. An overlay drawer looks modal but doesn't trap focus, so move focus into it yourself if your design needs that. And the toggle button should set aria-expanded to match the drawer's state.

Common questions about the Quasar drawer

Why is mini mode ignored on my phone? Mini only applies in desktop behavior. Below the breakpoint, the drawer is a full slide-over by design.

How do I keep the drawer closed on desktop until the user opens it? Remove show-if-above and start the v-model as false.

The drawer swipe fights with Safari's back gesture on iOS. What do I do? Add no-swipe-open, and no-swipe-close if needed. The swipe-to-open strip is a 15px band along the screen edge, so no-swipe-open also helps when a q-page-sticky button sits on that edge.

How do I make a drawer always slide over, even on a big screen? Set behavior="mobile". For a docked look that still floats over the page, use overlay instead.

Next step

If you'd rather start from a finished sidebar layout than wire one up, the Drawer Layouts Block has 11 Quasar layouts with a header, a drawer and page content. Three of them are free, including an icon rail in mini mode with a tooltip on every icon. Preview them, copy the code, and adapt the breakpoint and state handling from this post.