Skip to content

NotificationBell mobile sheet renders off-screen under a backdrop-filter ancestor (unportaled trigger variant) #44

Description

@ditto-m

Summary

<NotificationBell>'s mobile bottom sheet (the default variant="trigger", used per the README recipe <NavigationBar trailing={<NotificationBell items={items} />} />) renders squeezed near the top of the screen instead of docked to the viewport bottom, when NavigationBar has picked up the Liquid Glass .etu-glass material (the default — both .etu-navbar and .etu-mtb opt into it per the README).

Root cause

.etu-notif-bell-sheet is position: fixed; bottom: 0. Per the CSS spec, backdrop-filter (like transform/filter/perspective/will-change: transform) establishes a new containing block for position: fixed descendants. .etu-glass sets backdrop-filter: blur(24px) saturate(180%), so once the sheet's ancestor chain includes a .etu-glass element (here, .etu-navbar.etu-glass, sticky at the top), the sheet's bottom: 0 resolves against that ~48px-tall navbar box instead of the real viewport — the sheet ends up mostly clipped above the visible screen.

The row variant already avoids this: NotificationBell's isRow panel is portaled to document.body via createPortal (see the "Popovers inside the sidebar must be portaled" note in the README). The default variant="trigger" panel — including its mobile bottom-sheet form — is not portaled, so it inherits whatever containing block its mount point happens to sit inside.

Repro

  1. Mount <NavigationBar trailing={<NotificationBell items={[]} push={{...}} />} /> per the README's documented mobile recipe.
  2. Open at a mobile viewport (<720px) with a non-empty push (so the row has content) or any items.
  3. Click the bell trigger.
  4. The sheet renders with most of its height above y=0 instead of sliding up from the bottom.

Confirmed via getBoundingClientRect() + walking ancestors for transform/filter/backdrop-filter/will-change/contain.etu-navbar.etu-glass's backdrop-filter is the containing-block trigger.

Suggested fix

Portal the trigger-variant's mobile sheet (and arguably the desktop popover too, for the same reason) to document.body, the same way the row variant already does — rather than relying on the consumer's ancestor chain never setting backdrop-filter/transform/filter.

Workaround in place

etamong-playground/res-train (planning#1149 / #1147 adoption PR) drops .etu-navbar's backdrop-filter specifically at the mobile tier (@media (max-width: 719px) { .etu-navbar.etu-glass { backdrop-filter: none } }) until this portals upstream. Losing the glass blur on the mobile top bar is an acceptable trade until fixed here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions