Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure anchored components are always rendered in a stacking context #3115

Merged
merged 2 commits into from
Apr 19, 2024

Conversation

RobinMalfait
Copy link
Collaborator

@RobinMalfait RobinMalfait commented Apr 19, 2024

This PR ensures that components with the anchor prop always use the floatingStyles from Floating UI (which contains position: absolute).

This is important, otherwise there is a brief moment where the <ListboxOptions anchor={…} /> (in case of a Listbox) is rendered at the end of the page.

One side effect of this is that this could cause a scrollbar to appear for a moment. But the anchor prop also renders the component in a Modal which does scroll locking (by applying overflow: hidden; to the body).

A side effect of adding overflow: hidden is that the scrollbar is removed. This is nice, but this causes a visual jump when the scrollbar is removed. To counteract this, we also add a padding-right based on the width of the scrollbar to the body to prevent the visual jump.

But because of the brief moment where the scrollbar is visible, we also add a padding-right to the body to prevent the visual jump actually which now causes a visual glitch now. Head scratcher...

Long story short, no more accidental scrollbar appearing for a brief moment.

Before this change, we were only providing the `floatingStyles` based on
the `isEnabled` state. However, this relies on information that is only
available in the next render.

Now the styles are provided one render too late. This means, that there
will be a moment where the `ListboxOptions` (in case of a `Listbox`) is
rendered at the end of the page (and expanding the height of the parent)
without positioning it on top of it in a separate layer (due to the
`position: absolute;`)

The reason this was added was to prevent applying styles to the
`ListboxOptions` if it did not require anchoring (aka no `anchor={{…}}`
prop is provided).

Instead of relying on the `isEnabled` value (which is computed based on
information that is only available in the next render), we provide the
styles based on the incoming `anchor` information which is available
immediately.

The cool thing is that Floating UI is already providing a default
`position: absolute; top: 0; left: 0;` style. If we apply this, it's
already stacked instead of rendering at the end of the page.
Copy link

vercel bot commented Apr 19, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
headlessui-react ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 19, 2024 10:59pm
headlessui-vue ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 19, 2024 10:59pm

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.

None yet

2 participants