HTML is eating JavaScript UI libraries

We've all probably heard about the HTML dialog element, popover API, and customizable select, but I think a lot of people don't realize how powerful and battle-tested they are and also might not know about some of the inconsistencies these elements have and that they might encounter when using them. And this is what this post is about, I'm not going to go over the syntax and basic API's, if you're unfamiliar with them, I would suggest you read some MDN pages and Chrome For Devs blog posts before you jump into this article. I would like to focus more on in-depth details and edge cases. The article will be a comparison between these native elements and UI libraries like Shadcn, React Aria, etc.

You can get a better reading experience from the link above, it's demos and code snippets for better understanding. If you complete reading the article, tell me about your thoughts in the comments below.

Let's start by listing out some of the common features you would expect from a robust dialog, select, or popover, whether it's native or custom JS one.

  • Keyboard-navigatable: if it's a dialog, it should be focus trapped, it's a select, it should navigate using arrow keys, etc.
  • Escape key dismissal
  • These floating element/pop ups should, under all circumstances, appear above the rest of the page content, and as we will see, there are different mechanisms to approach this.
  • Mobile back button/swipe gesture: you probably didn't think about it, but on desktop, you use Escape key to close, but what do you do on mobile? If you're like me on Android, you can close things using the back button or swipe gesture, our dialog/select should support that too, otherwise, it's gonna jump the browser back in history, which creates a bad user experience, especially if we're building something that will be heavily used by mobile users, like a social media app or something, I've tested this on multiple social media apps like Facebook and Twitter (not going to call it X whatsoever), they all, either fully or partially, support back button press in some form. For example, on Facebook, I tried every possible menu or dialog I could think of, and they all close when I hit back button (and it's awesome).

I don't know if I missed something, but let's just focus on these four features for now and see how native elements vs UI libraries approach them, as we'll see, there's a lot to unpack in here.

For keyboard navigation and Escape key dismissal, the HTML dialog, select, popover, and all the upcoming elements have this built-in, you almost don't need any JavaScript at all for any of this to work, but for JS libraries, it's an entirely different story, you'd be shipping tons and tons (or even hundreds) of lines of JS for Escape key dismissal, arrow keys navigation, focus trapping, etc. All of this just to re-invent what the browser gives you for free.

For back button/swipe gesture, this is also already built-in in the native components, all of them close on back button press on Android, but in UI libraries like Radix UI or React Aria, they don't even have this feature at all, despite that it can be added using JavaScript.

In order to add support for back button press and swipe gestures, you can use the CloseWatcher API, as MDN says: it allows a custom UI component with open and close semantics to respond to device-specific close actions in the same way as a built-in component.

The browser compatibility for the CloseWatcher API is decent, it's been in Chrome and Edge since June 2024, Firefox added it in May this year (2026), it's not available in Safari yet, but this is a progressive enhancement feature, if it's available, your users are going to enjoy a better experience, if it's not, it's not a big deal. Also, you can build this same behavior using the HistoryAPI if you need it that much.

The Top Layer

One thing I want to compare is how native elements and UI libraries make sure things appear on top of other page content and also above each other. To better explain this, let's take the following example from Notion webapp, here we have the settings dialog and inside we have a select that we can choose our preferred theme from. The question is how do we ensure the dialog appears above other content and the select appears above the dialog.

Please continue reading the post from the link above, Reddit posts don't support demos and multiple images. If you complete reading the article, tell me about your thoughts in the comments below.

submitted by /u/Successful-Shock-802
[link] [留言]