Recently I was introduced to the
<dialog> tag and thought it was an interesting use of a web component pattern, but immediately I questioned the API and indeed after some minor digging, there really are some glaring issues regarding their use in terms of security, and as a major annoyance.
isThereAlreadyAModalOpen? and disallow any future
showModalcalls to avoid flooding the browser with dialogs and to have a way to always guarantee their closing, but I have been working on a solution for that below.
I’ve put them together in a Codepen and there are 4 main hacks:
- Adding a listener over a close button to make it nearly impossible for the user to close it.
- Having a close button that when pressed closes the modal but also triggers an undesirable path.
- 2 Buttons that send you into an loop of death in creating modals.
- Hijacking the Escape (and Tab) button
The whole thing calls itself to get into a loop if you press the right buttons. Below are the issues I found:
One issue is that you pretty much have full control over the DOM element of the dialog. This is good in many ways, but with great power…
With our annoying button, we use this to control the
transform style of the modal itself and move it beyond the reach of the user. We add a second button that does close the modal using a call to
But of course most users might try press the Escape key in hopes that whatever is on the screen will disappear, but we have that particular route covered.
In this case we hijack when we detect the keycode for the Escape key,
ASCII 27 and we use it to just keep clicking the open button for creating the modal.
However it’s worse than that! As an added bonus pointed out to me if you also check for
ASCII 9, 13 and 32 as the Tab, Enter and Space characters so you can also punish the user for trying to use the keyboard to close the modal. The code that captures them, and the arrow keys is:
const eventKeys = [9, 13, 27, 32, 37, 38, 39, 40]; // Capture Escape, Enter, Tab, Space and arrow keys
It’s quite easy to create a stack overflow with the dialog by just calling a
setInterval on it:
Hopefully you enjoy the demo and this post, and this gives some pause for thought too in how we sometimes implement and use browser features. Users have already been taught bad habits for hitting buttons, especially on OSX these days.