The Dropdown You've Been Faking for a Decade
Design wants a country picker. Nothing fancy — a dropdown, a small flag icon next to each name. You reach for <select> , type the first <option> , and hit the wall every frontend dev hits eventually: an <option> can only ever show text. No <img> , no icon span, nothing. The browser renders whatever markup you put inside it as a plain string. So you do what everyone does. You build a fake one. The…
Design teams often create their own dropdown components to add icons to the options. However, the standard HTML select element has limitations — it can only display text, not images. To work around this, developers tend to build their own dropdowns using divs and buttons, resulting in custom code that's not as robust as the native select element.
One approach is to use ARIA roles and attributes, creating a role="listbox" div with role="option" children containing the actual markup. This allows for keyboard navigation and screen reader compatibility. However, positioning issues arise when the dropdown is placed inside a card component with overflow: hidden. The custom popup gets clipped by the card's edges, even though it's a child of a parent div.
The solution is to use the new CSS property `appearance: base-select;`. This tells the browser to style the custom dropdown like a native select element, including the ability to have real markup in the options. Additionally, using the `::picker(select)` pseudo-element allows the custom dropdown to be positioned above the clipping container, avoiding the overflow issue entirely.
While this custom dropdown solution requires a bit of CSS work, it eliminates the need for complex JavaScript code and provides a more accessible and maintainable solution. However, support for this feature is not universal yet, so it's recommended to use feature detection and provide fallbacks for browsers that don't support it. This way, users can still benefit from the dropdown functionality while avoiding the pitfalls of a hand-rolled component.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.