Search code examples
cssreactjsantd

Antd select and autocomplete list elements 'stick' on inner element scroll


I have a reproduction of the issue on this sandbox: https://codesandbox.io/s/53lnxrwl2k.

What I'm doing there, is setting body, html, #root, .App to height: 100vh; and then having my main flex grow to fill the rest of the viewport, and essentially act as the scrolling area of the application.

html,
body,
#root,
.App {
  margin: 0;
  padding: 0;
  overflow-y: hidden;
  height: 100vh;
}

main {
  overflow-y: scroll;
  flex: 1 0 auto;
}

The problem is - if I select an item in the Antd autocomplete - and then I scroll - you can see that the list contents stay on place.

enter image description here

If we inspect the HTML, we can see what it is that Antd inserts the list contents as a separate div element, outside of the react #root element, and applies fixed styling to it:

<div class="ant-select-dropdown ant-select-dropdown--single ant-select-dropdown-placement-bottomLeft" style="width: 200px; left: 158.781px; top: 126px;">
  <div style="overflow: auto; transform: translateZ(0px);">
   <ul role="listbox" class="ant-select-dropdown-menu  ant-select-dropdown-menu-root ant-select-dropdown-menu-vertical" tabindex="0">
      <li role="option" unselectable="on" class="ant-select-dropdown-menu-item" aria-selected="false" style="user-select: none;">Burns Bay Road</li>
      <li role="option" unselectable="on" class="ant-select-dropdown-menu-item" aria-selected="false" style="user-select: none;">Downing Street</li>
      <li role="option" unselectable="on" class="ant-select-dropdown-menu-item" aria-selected="false" style="user-select: none;">Wall Street</li> 
    </ul>
  </div>
</div>

The important part being:

style="width: 200px; left: 158.781px; top: 126px;">

So what it seems like is what is happening is that Antd is adjusting that style on window scroll - but because my scrolling element is nested - it doesn't detect it to change.

Is there an easy fix to solve this?

Update: This issue seems to be with rc-select - as this repro demonstrates: https://codesandbox.io/s/x2k94o4o9o


Solution

  • As per the author comment you need to set the position relative to container and set the container as popup container, there is property called getPopupContainer in this plugin.

    like this

      <div id="testPosition" style={{ position: 'relative' }}>
                hello
                <Select
                  getPopupContainer={() => document.getElementById("testPosition")}
                  style={{ width: 100 }}>
                  <Option value="jack">jack</Option>
                  <Option value="lucy">lucy</Option>
                  <Option value="yiminghe">yiminghe</Option>
                </Select>
              </div>
    

    Demo