[material-ui][Popover] Incorrect position inside CSS inline-size container
Steps to reproduce
Link to live example: https://codesandbox.io/p/sandbox/mui-container-query-wtzlg5?file=%2Fsrc%2FDemo.tsx
Steps:
- Tick the "Disable portal" checkbox
- Click the "Open popover" button
Current behavior
The popover is mispositioned when disablePortal flag is set
Expected behavior
The popover should be positioned the same regardless of the disablePortal flag
Context
In our app we have a reusable form field component that uses container queries for different layouts depending on available size. Some form fields use the MUI Popover component, eg. to display a calendar in a date input field.
Your environment
npx @mui/envinfo
System:
OS: macOS 14.3.1
Binaries:
Node: 19.6.0 - ~/.nvm/versions/node/v19.6.0/bin/node
npm: 9.5.0 - ~/.nvm/versions/node/v19.6.0/bin/npm
pnpm: 8.6.12 - ~/.nvm/versions/node/v19.6.0/bin/pnpm
Browsers:
Chrome: 121.0.6167.184
Edge: Not Found
Safari: 17.3.1```
</details>
**Search keywords**: mui popover inline size disableportal
In the codesandbox example above you can see the popover is offset by exactly the amount of top padding outside the container.
The positioning of the popover breaks due to the fact that CSS containers seem to create a new stacking context. Therefore the popover container (.MuiPopover-root) no longer covers the whole screen but only the container:
Edit: consequentially this also affects the outside click handler
Thanks for reporting. It seems that the Material UI Popover component's positioning calculations don't account for the layout of containers. If the container has a type other than normal, the positioning should be relative to the container rather than the window.
In the future, Popover may be replaced by Popup from Base UI, which uses Floating UI internally and considers the containing blocks in its calculations. Here's an example demonstrating how Base UI Popup handles positioning correctly with inline-size container: https://stackblitz.com/edit/vitejs-vite-pvnhbj?file=src%2FApp.tsx.
I'll mark this as a bug though.
Hi, .When the 'disable portal' option is unchecked, the popover (simple-popover) is rendered in the body as a direct child and sibling element of our app (#root).
.When the 'disable portal' option is checked, the popover (simple-popover) is rendered next to the 'Open Popover' button." please check the attached images
That's why ".presentation/simple-popover" is not taking the full width of the window.
That's why ".presentation/simple-popover" is not taking the full width of the window.
Even if it's rendered as a child, it has position: fixed and is positioned relative to the container. If there's no container, it is positioned relative to the browser window due to position: fixed.