October 14, 2026 - 20:48
Build a Modal with HTML, CSS and JavaScript Image
HTML5 & CSS3

Build a Modal with HTML, CSS and JavaScript

Comments

A modal is useful when a short task needs the reader's attention without leaving the page. A dark overlay alone does not make a component modal: keyboard users must also be prevented from wandering into the page behind it. For a small standalone example, the native dialog element avoids rebuilding that behavior from scratch.

This is a framework-free companion to our original modal video. It does not load Bootstrap or reproduce Bootstrap's JavaScript API. If your existing project already uses a modal library, use that library consistently instead of letting two implementations manage the same element.

A complete example you can save as an HTML file

Save the following as modal.html and open it in a modern browser. The button opens a short information panel; the Close button and Escape dismiss it. Clicking the backdrop intentionally does not dismiss this example.

HTML
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Native modal example</title>
<style>
  body { font: 1rem/1.6 system-ui; margin: 2rem; }
  button { padding: .65rem 1rem; cursor: pointer; }
  button:focus-visible { outline: 3px solid #165dba; outline-offset: 3px; }
  dialog { box-sizing: border-box; width: min(32rem, calc(100% - 2rem));
    max-height: 85vh; overflow: auto; border: 0; border-radius: .7rem;
    padding: 1.5rem; color: #182334; background: white; }
  dialog::backdrop { background: rgb(0 0 0 / 65%); }
</style>
<h1>Delivery information</h1>
<button type="button" id="open">Read delivery details</button>
<dialog id="details" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Before you place an order</h2>
  <p>This demonstration does not submit an order or collect personal data.</p>
  <form method="dialog">
    <button autofocus>Close</button>
  </form>
</dialog>
<script>
  const opener = document.querySelector('#open');
  const dialog = document.querySelector('#details');
  opener.addEventListener('click', () => dialog.showModal());
  dialog.addEventListener('close', () => opener.focus());
</script>
</html>

Which part controls the interaction?

showModal() opens the modal and makes the rest of the document inert. Simply adding an open attribute does not provide the same modal behavior. The heading supplies an accessible name through aria-labelledby; the Close button receives initial focus. A form using method="dialog" closes the panel without sending a network request. These behaviors are documented in MDN's dialog reference.

The explicit close listener returns focus to the opener in this example. If you later remove that opener or navigate to a different view, choose a meaningful new focus destination instead. Do not add a second hand-written Tab trap around the native dialog without a specific, tested reason.

Try the awkward cases before reusing it

Open the panel using only the keyboard, press Tab repeatedly, close it with Escape, and reopen it. Then enlarge the browser text and replace the short message with several paragraphs. The content should remain reachable through the panel's scrollbar. Keep an obvious close control visible rather than relying only on a keyboard shortcut.

For a destructive action, add separate Cancel and Confirm controls and put initial focus on the safer choice. Closing a dialog is not proof that the user confirmed an action: only your explicit confirmation handler should perform that action.

Watch the original walkthrough

The original Netopsiyon video below is narrated in Turkish. Watch the demonstration on our YouTube channel alongside this English guide. The example in this article is an independently updated implementation, not a word-for-word transcript.

Watch this tutorial on YouTube.

Related Articles

Comments ()

No comments yet. Be the first to comment!

Leave a Comment