Skip to main content
Vuetify0 v1.0 is here
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

useStack

Overlay z-index coordinator with automatic stacking order and parent-child nesting support.

Edit this page
Report a Bug
Open issues
View on GitHub
Copy Markdown

PreviewIntermediateAug 12, 2026

Installation

Install the Stack plugin in your app’s entry point:

main.ts
import { createApp } from 'vue'
import { createStackPlugin } from '@vuetify/v0'
import App from './App.vue'

const app = createApp(App)

app.use(
  createStackPlugin({
    // optional: app-wide Portal fallback when no per-component `to` is set
    default: 'top-layer',
  })
)

app.mount('#app')
Tip

For client-side only apps, you can skip plugin installation and use the default stack singleton directly. The plugin is required for SSR to ensure each request gets its own stack instance.

Usage

Use the useStack composable to register an overlay and receive its z-index and position in the stack:

ts
import { shallowRef, watch } from 'vue'
import { useStack } from '@vuetify/v0'

const isOpen = shallowRef(false)

const stack = useStack()
const ticket = stack.register({
  onDismiss: () => { isOpen.value = false }
})

// Activate when opening, deactivate when closing
watch(isOpen, open => {
  if (open) ticket.select()
  else ticket.unselect()
})

// ticket.zIndex.value = 2000 when first overlay
// ticket.zIndex.value = 2010 when second overlay
// ticket.globalTop.value = true when this is the topmost overlay

Context / DI

Use createStackContext when you need a separate z-index namespace (e.g., overlays inside a modal):

ts
import { createStackContext } from '@vuetify/v0'

const [useModalStack, provideModalStack, modalStack] =
  createStackContext({ namespace: 'my:modal-stack', baseZIndex: 3000 })

// In parent component
provideModalStack()

// In child overlay component
const stack = useModalStack()
const ticket = stack.register({ id: 'tooltip-1' })
ticket.zIndex.value  // z-index for this overlay

Architecture

createStack extends createRegistry with z-index management and scrim coordination:

Stack Hierarchy

Use controls to zoom and pan. Click outside or press Escape to close.

Stack Hierarchy

Reactivity

Stack state and ticket properties are reactive for automatic UI updates.

PropertyReactiveNotes
isActiveAny overlays selected
topTopmost overlay ticket
scrimZIndexZ-index for scrim element
isBlockingTop overlay blocks dismissal
topElementElement of the topmost open modal (<dialog>), or null; consumed by Portal/Snackbar.Portal via teleport="top-layer"
defaultApp-wide Portal teleport fallback from createStackPlugin({ default })
ticket zIndexComputed from selection order
ticket globalTopTrue if topmost
ticket isSelectedOverlay active state

Examples

Overlay Stack

Three overlays — Settings, Confirm, and Alert — share a single createStack instance scoped to the example via provide('v0:stack', stack). Each overlay registers with stack.register({ onDismiss }) and calls ticket.select() / ticket.unselect() to activate or deactivate. The stack computes ticket.zIndex automatically based on registration order, so the third overlay always renders above the second.

StackProvider creates the isolated stack and wires the Scrim component alongside it — Scrim reads from the same context, so its z-index is always coordinated with the topmost overlay without any manual calculation. The Alert overlay uses blocking: true, which prevents dismissal via the scrim click (ticket.globalTop is still true, but the stack’s isBlocking flag tells the scrim to ignore pointer events).

Open multiple overlays to see z-index layering in action. This pattern applies directly to any overlay surface — dialogs, drawers, notification toasts — because the stacking logic lives entirely in createStack, not in the overlay components themselves. For SSR, install createStackPlugin at app level instead of calling createStack directly. See Scrim for the backdrop component and createRegistry for the underlying registry pattern.

FileRole
context.tsDefines the overlay shape and provides a typed context via createContext
StackProvider.vueCreates an isolated createStack, provides it to descendants, and renders the Scrim
StackConsumer.vueRenders buttons to open each overlay and displays their active z-index
overlays.vueEntry point that composes Provider around Consumer
Stack:
empty
Theme
Mode
Palettes
Accessibility

Recipes

Top-Layer Teleport

Pass el when registering a modal overlay so useStack().topElement resolves to its DOM element. Portal and Snackbar.Portal read topElement when teleport="top-layer" (the Snackbar.Portal default), teleporting overlays into the topmost open modal’s subtree so they share its top-layer context and stay interactive:

ts
const stack = useStack()
const ticket = stack.register({
  el: () => dialogRef.value?.element,
  onDismiss: () => { isOpen.value = false },
})

Dialog and AlertDialog pass their <dialog> element automatically — this pattern is only needed when building a custom modal component from scratch.

Default Teleport

Set an app-wide Portal fallback so every Portal without a to prop inherits the same target:

ts
app.use(
  createStackPlugin({
    default: 'top-layer',
  })
)

Resolution order:

  1. per-component to prop

  2. stack.default (from the plugin option)

  3. 'body'

'top-layer' still resolves to the topmost open modal element (via topElement), then falls back to 'body' when no modal is active - same as a per-component to="top-layer".

Scrim Integration

Use the Scrim component alongside useStack to provide a backdrop for your overlays. The Scrim automatically positions itself below the topmost overlay:

vue
<script setup lang="ts">
import { Scrim } from '@vuetify/v0'
</script>

<template>
  <Scrim class="fixed inset-0 bg-black/50" />
</template>

The Scrim reads from the same stack context, so its z-index is always coordinated with your registered overlays.

FAQ

Discord
Need help? Join our community for support and discussions ↗

API Reference

The following API details are for the useStack composable.
Was this page helpful?

© 2016-1970 Vuetify, LLC
Services
Ctrl+/