Skip to content

fix(Portal): apply position:relative so z-index creates a stacking context#602

Open
sridhar-3009 wants to merge 1 commit into
vuetifyjs:masterfrom
sridhar-3009:fix/portal-zindex-stacking-context-554
Open

fix(Portal): apply position:relative so z-index creates a stacking context#602
sridhar-3009 wants to merge 1 commit into
vuetifyjs:masterfrom
sridhar-3009:fix/portal-zindex-stacking-context-554

Conversation

@sridhar-3009

Copy link
Copy Markdown
Contributor

Closes #554

Problem

Portal.vue exposes zIndex as a slot prop but is itself renderless — it renders no DOM element. SnackbarPortal applies that zIndex to an Atom wrapper div via style: { zIndex }, but the div has position: static (the browser default). CSS ignores z-index on non-positioned elements, so the computed value has no effect. When a snackbar teleports to <body> it lands behind any positioned page chrome (e.g. .app-shell-content { z-index: 1 }) regardless of how large its stack-assigned z-index is.

Reproduced via #279: docs' .app-shell-content { z-index: 1 } sat above a body-fallback Snackbar.

Fix

Add position: 'relative' alongside zIndex in SnackbarPortal.getSlotProps. position: relative without offsets is visually neutral — the element stays in normal flow at its natural position — but creates a stacking context so z-index takes effect.

Also update Portal's PortalSlotProps.zIndex JSDoc to document the contract: the element receiving zIndex must be positioned.

Changes

  • SnackbarPortal.vue: getSlotProps now returns style: { position: 'relative', zIndex } and the SnackbarPortalSlotProps type is updated to match
  • Portal.vue: PortalSlotProps.zIndex gains a @remarks noting the positioned-element requirement

…ntext (vuetifyjs#554)

Portal hands out a computed z-index via its slot prop, but `z-index` is
only effective on *positioned* elements (position: relative/absolute/
fixed/sticky). When SnackbarPortal teleports to `<body>`, the wrapper
Atom div had `position: static` (the browser default), so the computed
z-index was silently ignored and the snackbar sank beneath any positioned
page chrome (e.g. `.app-shell-content { z-index: 1 }`).

Fix: add `position: 'relative'` alongside `zIndex` in SnackbarPortal's
`getSlotProps`, giving the wrapper a stacking context without affecting
its visual position. Also document the requirement in Portal's slot-prop
JSDoc so other consumers know to position the element they apply `zIndex`
to.
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ No changeset found

This PR changes packages/* source but has no changeset, so it won't be in the next release's version bump or notes. Add one:

pnpm changeset

Pick the affected package(s) — @vuetify/v0 carries @vuetify/paper automatically; @paper/genesis (and other @paper/* design systems) version separately — a bump type, and a short summary, then commit the generated .changeset/*.md. Docs-only, chore, or CI PRs can ignore this.

@johnleider johnleider added this to the v1.0.x milestone Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug Report] Portal z-index inert without a positioned wrapper

2 participants