Is there a limitation in CSS preventing it?
This runs counter to the behavior of it being anchored to a parent container.
-1-----------
| |
| -2--- |
| | D | |
| ----- |
| |
-------------
If you attach the dropdown options to the inner container (2), they are cropped.If you attach the dropdown options to the outer container (1), they don't scroll with the rest of their component (D).
----
Non-native dropdowns in general are handicapped.
For Windows/MacOS/Linux, native dropdowns can exceed the bounds of even the OS window. There is no CSS equivalent of this behavior.
I've been interested in re-implementing smooth scrolling in JS to mimic native but.. Even if you hit solid native refresh at all time, I feel you'd have to switch your entire site to JS controlled scrolling for consistency and even then the scroll feel might not match native scroll on other pages per system settings.
It's a bit of a rabbit hole.
Embrace what the web exposes. Allowing document scrolling underneath is distinctly the lesser of two evils. With a bit of effort, you can block scrolling underneath in almost all cases, and I reckon that’s good enough and much better than what there is currently. (Also try asking browser makers, “y’know this ‘top layer’ thing you made for <dialog> modal presentation and fullscreen? Wouldn’t it be nice if we could prevent scrolling underneath a ::backdrop?”)
The page applies `overflow: hidden` to the root element, which isn’t a very good solution to the “you shouldn’t be able to scroll the document while a dropdown is open” problem. It tries to counteract the scrollbar shift problem this causes by applying corresponding padding to the root element (which is still yuck, because the scrollbar still visually disappears, which it shouldn’t), but the page uses `position: fixed` for the header and right ToC sidebar, which bypasses the document padding. End result, opening a dropdown shifts parts of the document, which is bad.
I’m not sure if there’s a proper solution that makes it behave how a <select> does on desktop platforms; historically there wasn’t, and every historical workaround causes worse problems than it solves, in my opinion. Also in my opinion, the problem was never particularly important; the only part that was even vaguely notable was scroll chaining, and you can now just specify `overscroll-behavior: contain` on the dropdown popup to categorically fix that. (Browser support: 7½ months in Safari, 5–6 years elsewhere.) Very recently, browsers have been getting better support for modal concepts, driven by the <dialog> element and the corresponding concept of a top layer, as the spec calls it. I haven’t played with it, but I suspect that this might finally be the actual solution to the problem of stopping scrolling underneath.
Popper supports putting popper elements somewhere else in the DOM, but that’s not their general recommendation (https://popper.js.org/docs/v2/performance/#attaching-element...).
React Aria puts its popups in such a separate place in the DOM like you’re saying.
But the part I and the parent were remarking upon is what you do about scrolling.
Popper’s (default) answer is “recalculate the preferred position [and size, I think?] on every scroll event”. This is perfectly fine, and sometimes preferable.
React Aria’s answer is “position once and then prevent scrolling”. This matches all platforms’ conventions for these sorts of elements, it’s just that the way they’ve implemented it has problems, problems that may be unavoidable at present.
In any case I'm sure they will fix it if you open an issue against it..
The “Favorite Animal” dropdown shown in the linked page can be done with <select> with no loss, and therefore I’d say probably should be. But you can often do much better by skipping past <select>:
• Use more than just plain text in each option (very simple example: https://react-spectrum.adobe.com/react-aria/Select.html#comp...; also think of things like adding icons)
• Support typing on all platforms (and no, native combo boxes à la <input list="…"> + <datalist> aren’t far off completely useless in practice).
• Support typing with more complex matching, e.g. in a country selector supporting US/USA/United States, NL/Netherlands/The Netherlands/Holland, &c.