floating-ui / floating-ui

A JavaScript library to position floating elements and create interactions for them.
https://floating-ui.com
MIT License
29.53k stars 1.59k forks source link

Absolutely positioned child with negative transforms always takes the top space and gets clipped off #2964

Closed arunks5 closed 1 month ago

arunks5 commented 1 month ago

I have reproduced the issue here

I have a container (class=modal__body) which is 150px height and overflow as auto Inside the container, i have a text passage and an input-field. This input-field is the reference element and has position as relative. On clicking of the input, our floating element is displayed which is positioned absolute and transformed using floating-ui.

In the floating ui config, if I provide autoPlacement({ allowedPlacements: ['bottom-start','bottom-end'] }),

the floating element is displayed below and our container scroll appears which looks good.

But, if I provide autoPlacement({ allowedPlacements: ['bottom-start', 'top-end', 'bottom-end', 'top-start'] }),

the floating element always displays at the top-end and it is clipping off.

Steps to reproduce the behavior:

  1. click on the input field
  2. floating element appears which is clipped off

Expected behavior Even when the allowedPlacements has ['bottom-start', 'top-end', 'bottom-end', 'top-start'], floating ui should know that the element will be clipped off by the overflow container and should display below, since if displayed below atleast we can scroll to see the floating element.

We need to provide all four placement because, in this scenario, it is clipping off on the top. But in other scenarios , floating element can be displayed on top without clipping off, if it is not placed inside a container with max-height.

Screenshotsimage

Context:

atomiks commented 1 month ago

This is kind of an ambiguous case given it's only valid when the scrolling direction is top-down. I don't think it's wise to make it aware of this kind of scrolling context (in that the floating element being inserted allows it to scroll down). The most obvious solution here is to ensure the floating element doesn't get clipped by this small container by appending it to a node outside.