DEV Community

Cover image for Do We Even Need Modals?
Rostislav B
Rostislav B

Posted on

Do We Even Need Modals?

Ever feel like the web could use some design police? No one enforcing consistency, no standards for how things should behave. Just pure freedom. And somehow, in all that freedom, modals became the answer to everything. Forms, confirmations, settings, edit screens. Whatever the question, modal was the answer. Not because they're particularly good at any of this, though. Just because they're easy to reach for when you need something to work.

What's Actually Wrong With Modals

Here's the core problem: modals block context. The page you were working on disappears behind a dark overlay, and if you need to check something in that table before filling the form, you're stuck — close the modal, look at the data, open it again, hope the state survived. It probably didn't.

The accidental dismissal problem makes this worse. Click outside and the state is gone. Hit Escape by habit — same result. Three required fields filled, but you accidentally touched the backdrop, and now you're starting over. Sound familiar? Because this isn't some edge case. It's just how most modals work out of the box.

Have you ever tried sending someone a link to a modal? Some implementations do support URLs, but it's rare enough that most people never think to try. Modals tend to exist outside the navigation model: no back button, no way to return. In a world where client-side routing makes page transitions essentially free, we're still building these floating islands with no address.

On mobile, the situation gets stranger still. Modals become fullscreen, which defeats the entire purpose. If it takes the whole screen anyway, why not make it a page with proper navigation?

And then there's async. Submit a form in a modal and suddenly you're making decisions nobody thought about upfront: where the loader goes, which buttons to disable, whether the modal closes on request start or waits for success. What happens to the content underneath while the spinner runs? Every team answers these differently, and the result is that no two modals behave quite the same way.

And in code, the complexity shows: isOpen, onOpen, onClose, handleClose, shouldClose. Every modal is a little state machine, though it's never quite clear where that state machine should live. In the component that triggers it? In a portal at root? In some global store? The answer is usually "wherever the last developer put it."

How Did We Get Here

Browser alerts exist: window.alert(), window.confirm(). They're built-in, accessible, and keyboard-friendly, which sounds like everything you'd want.

The problem is they're also ugly, completely uncustomizable, and terrifying to modern users. Most people see a browser dialog and assume something broke. You can't style them to match your design system, and good luck putting a form in one.

So we built our own. Custom divs layered on top of everything, dark overlay behind, trap the focus, listen for Escape. This solved the styling problem, but it created a dozen new problems that we're still dealing with.

What Native and Game Design Got Right

Think about the iOS date picker. You already know exactly what it looks like, how it behaves, what to expect. So does pretty much every designer and developer who's ever built for mobile. No debate about whether it should be a modal or inline or a separate screen. Standardization already solved that question.

Game interfaces, meanwhile, follow a different philosophy entirely: UI is part of the world, not a layer blocking it. Open your inventory and the game world stays visible. Need to check stats while crafting? Both panels coexist. Context is never fully blocked.

What makes this work, though? Partly standardization: when everyone knows how a component behaves, nobody wastes time reinventing it. But also, these interfaces don't hide anything behind an overlay. UI elements expand the layout, and you stay oriented because the thing you were looking at is still there. And when actions need confirmation, they flip the pattern: do the thing first, then offer undo. No interruption, just trust the user and give them a way back.

Alternatives For the Web

The simplest alternative is just... a page. I happened to work on a project where we replaced all modals with pages and back links. Client-side routing made transitions instant, URLs worked everywhere, state lived in the URL. It works on mobile, it's accessible by default. Feels heavy for small actions, sure. Not every "create new item" deserves its own route. But more things could be pages than we typically assume, even if whether they should be is a different question entirely.

For cases where a full page feels like overkill, sliding panels work reasonably well. The form slides in from the side while the main content stays visible, so you can still reference the table while filling out the form. Though panels have their own problems: they eat horizontal space, and on narrow screens they're basically modals again.

Confirmation dialogs have a cleaner replacement: toast with undo. Delete something and it's gone immediately, then a toast appears with an "Undo" button, five seconds to reverse the action. No "Are you sure?" dialog that everyone clicks through anyway. Gmail proved this works at scale, though it helps that email deletion is soft-delete anyway. For truly permanent actions, this approach gets murkier.

For editing, often no overlay is needed at all. Click a cell and it becomes an input, save on blur or Enter. Inline editing won't help with creating new entities, but it eliminates a whole category of "edit this one field" modals. And contextual menus (right-click or long-press) keep actions close to their objects rather than forcing a journey to a modal in the center of the screen.

When Modals Are Actually Right

The list is short, though maybe that's the point.

Destructive actions with no undo are the clearest case. If delete is permanent and there's no recovery, then blocking context is actually what you want, and this is probably the one situation where a modal earns its interruption.

Beyond that, you're looking at situations where you genuinely need acknowledgment before proceeding: legal consent, session expiry warnings, maintenance notifications. Cases where "just do it and offer undo" doesn't work because there's nothing to undo.

That's... mostly it?

The Designer Problem

Here's what happens. Team agrees on modal standards: header, body, footer, max height, scroll behavior, button placement. Seems reasonable.

Then second sprint comes around: "This one needs an interactive header." Third sprint: "Footer should change based on form state." Fourth sprint: "Can we have tabs inside?" By fifth sprint, welcome to modal hell.

You'd think there'd be some guardrails — but the web won't stop you from putting tabs inside a modal inside a drawer. If it renders, it ships. So people do whatever feels right in the moment. Every modal becomes a special case, composition explodes, and the component that started as <Modal title="Create Item"> becomes a 200-line monster with fifteen props.

Funny thing: the closest the web got to modal standardization was the <dialog> element, and most teams don't even know it exists.

The Actual Point

Nobody's saying modals are evil. But they've become the default answer to a question that most teams stopped asking a long time ago. When someone clicks "Create Item," do they need to focus completely on the form, or would they rather keep the table visible for reference? A modal decides for them: full focus, context gone. A sliding panel makes the opposite bet, yet most of the time we reach for the modal anyway — not because we thought about which one fits, but just out of habit.

Maybe the habit keeps winning for a reason. Or maybe it just keeps winning because it's there, and nobody has time to rethink what already works well enough.

Top comments (0)