Free tools Windows power users keep installed
One-click scans. No signup required.
Use the native <dialog> element for a browser-managed dialog: call showModal() when the rest of the page must be blocked, or show() when it should remain usable. Close it with a dialog method or a method="dialog" form—not by manually removing its open attribute. Then test focus, keyboard dismissal, form results, and the non-modal case separately.
Choose modal or non-modal behavior
The important choice is whether opening the dialog should interrupt interaction with the rest of the document. The methods create distinct states; setting the open attribute is not a substitute for choosing between them.
| Method | Behavior | Use it when |
|---|---|---|
showModal() |
Opens a modal dialog in the browser’s top layer, displays its ::backdrop, and makes the rest of the dialog’s containing document inert. |
The user must make a decision or complete a task before returning to the page. |
show() |
Opens a non-modal dialog; the surrounding document remains interactive. | The dialog should offer supplementary content without blocking other page controls. |
In an iframe, a modal makes the iframe’s document inert, not the embedding page’s entire document. Treat that boundary as part of your design and test plan.
Build a working modal dialog
This example includes an accessible title, an opener, explicit decision buttons, and a result handler. The form closes the dialog without sending form data to a server; the activated button’s value is exposed as returnValue.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
<dialog id="confirm-dialog" aria-labelledby="confirm-title">
<h2 id="confirm-title">Delete this item?</h2>
<p>This action cannot be undone.</p>
<form method="dialog">
<button value="cancel" autofocus>Cancel</button>
<button value="confirm">Delete</button>
</form>
</dialog>
<button id="open-confirm">Delete item</button>
<script>
const dialog = document.querySelector("#confirm-dialog");
document.querySelector("#open-confirm").addEventListener("click", () => {
dialog.showModal();
});
dialog.addEventListener("close", () => {
if (dialog.returnValue === "confirm") {
// Perform the confirmed action.
}
});
</script>
The example deliberately gives initial focus to Cancel. Choose the initial target for your own task: for example, focus a safe action in a destructive confirmation. MDN recommends autofocus on the element that should receive immediate interaction; for complex or dynamically rendered content, focusing the dialog itself may be appropriate. Do not add tabindex to the <dialog> element itself.
Opening a non-modal dialog
Use the same element and content, but call dialog.show() instead of dialog.showModal(). Test that controls behind it remain usable. A dialog made visible simply by adding open is non-modal, but MDN recommends the display methods.
Style the modal backdrop
When a dialog is opened modally, style the browser-provided backdrop with the ::backdrop pseudo-element:
Rank #2
dialog::backdrop {
background: rgb(0 0 0 / 0.55);
}
The backdrop’s appearance is separate from the dialog’s content and does not replace an explicit visible close or decision control.
Close the dialog and handle its result
Use close() for direct closure
Call dialog.close() to close directly. You can pass a string to set the result available in dialog.returnValue, such as dialog.close("cancel").
Use requestClose() for a close request
requestClose() follows the close-request path: the dialog fires cancel first, and closes unless that event is canceled. It is useful when your code should follow the same cancelable path as a user-requested dismissal.
Rank #3
Use cancel and close for different jobs
Listen for cancel when you need to observe or prevent a close request, such as Escape. Calling event.preventDefault() in that handler leaves the dialog open. The close event fires after closure; use it to react to the completed close, including reading returnValue.
dialog.addEventListener("cancel", (event) => {
// Optional: prevent this close request when the task requires it.
// event.preventDefault();
});
dialog.addEventListener("close", () => {
console.log(dialog.returnValue);
});
Use method="dialog" for button results
A form with method="dialog" closes the dialog after successful submission rather than submitting its data to a server. The activated submit button’s value can communicate which choice the user made. Handle the result after closure through returnValue or the close event.
Do not remove open manually
Changing the open attribute by hand is not a safe way to close a modal. The HTML Standard warns that doing so does not fire the close event and can leave the document blocked. Use close() or requestClose() instead.
Test keyboard, focus, closure, and modality
These are behavior checks derived from documented browser behavior, not a claim that a particular implementation has been executed. Run them in the browsers and embedded WebViews your product supports.
- Activate the opener. Confirm that the intended method runs and the dialog opens in the expected modal or non-modal state.
- For
showModal(), try to activate a control behind the dialog. The rest of its containing document should be inert while the modal is open. - Check initial focus. Confirm that the intended control receives focus, including the effect of any deliberate
autofocuschoice. - Activate each explicit close or decision control. Confirm that the dialog closes and the
closehandler runs. - Press Escape on a modal dialog. Confirm the
cancelpath and, when it is not prevented, closure. Separately test that callingpreventDefault()in the handler keeps it open. - Submit every
method="dialog"button. Confirm closure and the expectedreturnValue. - Test
show()independently. The dialog should be open while the surrounding page remains interactive. - Repeat on the supported browser and embedded WebView matrix; a result in one browser does not establish behavior in every environment.
Use screenshots for appearance, not interaction proof
A screenshot can help review the visual state of a page, but an image alone cannot establish keyboard behavior, focus movement, whether background controls are inert, or whether a close event fired. Verify those behaviors in the browser using the checks above. If you capture a dialog state for visual review, ensure the page is actually in that state when captured.
Browser support and compatibility
MDN describes showModal() as widely available across browsers since March 2022. The HTML Standard’s compatibility notes list Firefox 98+, Safari 15.4+, Chrome 37+, and Edge 79+ for core dialog methods; Internet Explorer is unsupported. These are source-reported minimums, not a guarantee for every newer dialog feature or embedded WebView. Check the actual target environments, especially when relying on features beyond the core methods.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Best Value
Troubleshoot common problems
- The rest of the page is still clickable: Check whether the code called
show()or only setopen. UseshowModal()when the page must be inert. - The dialog closes but no result handler runs: Confirm that the listener is attached to the dialog and that closure uses a dialog method or a successful
method="dialog"submission. Manually removingopendoes not fireclose. - The result is empty or unexpected: For a dialog form, inspect the activated submit button’s
value; that value is what can becomereturnValue. For direct closure, pass the desired value toclose(). - Escape does not close the dialog: Inspect the
cancelhandler forpreventDefault(), which intentionally keeps the dialog open. Test whether that behavior is appropriate for the interaction. - The wrong control is focused first: Review your
autofocustarget and the content rendered when the dialog opens. Choose a suitable initial target for the task rather than relying on an assumed focus choice. - The behavior differs in a WebView or older browser: Compare the exact environment against your supported matrix and the source-reported core-method minimums. Do not infer support for additional dialog features from support for the basic methods.
Or skip the browser setup
For a visual capture of a page, ScreenshotNeo offers a one-request screenshot API. This is supplementary to the interactive browser tests above; it does not prove dialog keyboard, focus, or event behavior. Make sure the target page is in the state you intend to capture.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools




