Skip to content

Stacked dialog exit animation hidden by layer z-index reset #3207

Description

@Hwacc

🐛 Bug report

When stacked dialogs are used, closing the top dialog can make its content exit animation visually disappear. The Presence state and CSS animation events still run correctly, but the closing dialog's positioner loses its layer CSS variables during layerStack.remove(), causing its z-index to collapse while the node is still mounted for the exit animation.

💥 Steps to reproduce

  1. Using the official Zag.js nextjs examples -> Dialog examples -> Popover nested.
  2. Ensure the Dialog component is wrapped with Presence so that the close animation can play.
  3. Open D1 -> D2 -> D3
  4. Observe that D3/D2 content exit animation is not visible, or appears hidden behind the lower dialog/backdrop.

🧐 Expected behavior

The closing top dialog should keep its resolved stacking order until its exit animation completes. Its content and backdrop should remain visible while data-state="closed" animations are running.

🧭 Possible Solution

Freeze the resolved z-index before clearing layer style metadata in layerStack.remove().

layer.styleTargets?.forEach((getTarget) => {
  const target = getTarget()
  if (target) {
    const { zIndex } = getComputedStyle(target)
    if (zIndex && zIndex !== "auto") {
      target.style.setProperty("z-index", zIndex)
    }
    clearLayerStyleMirror(target)
  }
})

Then clear the frozen inline z-index when the layer is active again in syncLayers():

target.style.removeProperty("z-index")
applyLayerStackMetadata(layer, index, target)

🌍 System information

Software Version(s)
Zag Version 1.42.0
Browser Chrome
Operating System Windows

📝 Additional information

Please check the videos:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions