Website Popups

How to Create Modal Popups: Bootstrap, Tailwind, CSS and jQuery

A modal popup is a dialog box that opens on top of a web page and blocks the page behind it until the visitor answers or closes it. Build one with the HTML <dialog> element, Bootstrap 5.3, Tailwind CSS, pure CSS, legacy jQuery or a no-code popup builder; every version needs focus handling and Escape to close.

AI summarygeneral summary

Modal popups are triggered dialog boxes that show extra info without reloading a page, often used for forms, alerts, media, and tips; they can improve usability and load times if used well. The text covers building modals with Bootstrap, jQuery, or CSS, and recommends Popupsmart for fast, template-based creation and integrations.

Article facts

Written by
Paula Jones
Reviewed by
Mert Özeren
Published
July 14, 2022
Updated
October 1, 2026
Sections
10
Sources
7 cited

19 min read

Our editorial standardsHow we research, source and update every post.

On the web, modal popups usually carry newsletter signups, notifications and alerts, and login or registration forms.

There are several ways to build one with HTML, CSS and JavaScript. This guide goes through the Bootstrap Modal Popup, the jQuery Modal Popup and the CSS Modal Popup step by step, plus a native HTML <dialog> version and a Tailwind CSS modal. Every code example below was updated in October 2026: Bootstrap 5.3 without jQuery, Tailwind CSS v4, and jQuery kept only as a clearly labelled legacy option.

At the end, I'll show you a way to create and publish popups without code. First, though, why modal popups are used and why they matter.

How to Create Modal Popups? / Bootstrap & jQuery & CSS

Method Needs a library Focus, Escape and inert page built in Best for
HTML <dialog> + showModal() No Yes, from the browser Any new site; the default choice
Bootstrap 5.3 modal Bootstrap's JS bundle Yes, from Bootstrap Sites already on Bootstrap
Tailwind CSS + <dialog> Tailwind CSS Yes, from the browser Sites styled with utility classes
CSS-only (:target) No No Demos and static pages without JavaScript
jQuery (legacy) jQuery No, you write it Old sites that already load jQuery
No-code popup builder One embed code Handled by the builder Marketers who need a signup or offer modal live today

What is Modal Popup?

Example modal popup offering free shipping for an email, over a dimmed store page
Example design: a newsletter modal popup for a fictional online store. The page behind it is dimmed and waits until the visitor answers or closes the popup.

A modal popup or dialog box is a window that opens on top of the page the visitor is already on. The benefit of a modal popup is that it shows extra information without loading the page again. Visitors read what's relevant in the popup box and stay on the same page, which makes for a better user experience.

What makes it modal is that it takes over: keyboard focus moves into the popup, the page behind it can't be clicked or tabbed to, and the visitor has to answer or close it before going back. The page behind is still there, dimmed, exactly where the visitor left it.

A modal stays hidden until something triggers it. Then it puts one call to action, or one piece of information such as a signup form or an alert, in front of the visitor.

You'll find modal popups in a lot of places:

  • Inquiry/contact forms
  • Lead generation/signup forms
  • Login/registration forms
  • Search forms
  • Alerts/notifications
  • Help/tips
  • Displaying full-screen images & videos

Build your popups around what you want them to do. Alpma, for example, lets visitors log in from anywhere on the site.

A login modal popup that lets visitors sign in from any page of the Alpma website

Popups have a bad reputation. Used well, though, they can:

  • increase your website usability.
  • decrease the load times.
  • clarify all designs.
A modal popup dims and blocks the page; a non-modal slide-in leaves the page usable
Example design: the same page with a modal popup (left) and a non-modal slide-in box (right).

"Popup" is the umbrella word; "modal" describes how the popup behaves. A modal popup blocks the page until the visitor responds. A non-modal popup, such as a slide-in box, a sticky bar or a toast message, appears over part of the page and lets the visitor keep reading, scrolling and clicking.

Term Blocks the page? Typical use
Modal popup (modal dialog) Yes, until answered or closed Signup offer, login, confirmation
Lightbox Yes, usually over a dark overlay An enlarged image or video; many marketers also call a centred modal a lightbox
Non-modal popup (slide-in, sticky bar, toast) No Side offers, announcements, "saved" messages
Popover or tooltip No, anchored to the element that opened it Hints, menus, short help

Pick the modal when the visitor has one decision to make and nothing else on the page matters until they make it. For everything else, a non-modal format interrupts less. For the full list of formats, see our guide to the types of popups.

Across the popups we power, the centred format holds up for lead capture: Center modal popups convert 0.88% vs 0.49% for corner/slide-in boxes (median campaign) (Popupsmart popup benchmark 2026). That's a rate per popup display, and it doesn't make a modal the right answer everywhere: a modal still has to earn the interruption.

Info
Pro Tip: If the visitor could reasonably ignore your message and carry on, it isn't a modal. Put it in a slide-in or a bar, and keep the modal for the one thing you need an answer to.

What makes a modal popup accessible?

Accessible modal: focus moves in, Tab stays inside, Escape closes it, focus goes back
The four behaviours of the WAI-ARIA modal dialog pattern, in the order a keyboard user meets them.

An accessible modal popup does four things, and every code example in this guide is checked against them. They come from the WAI-ARIA modal dialog pattern:

  1. Focus moves into the modal when it opens, to its first field or its title.
  2. Tab stays inside. The page behind it is inert, so the keyboard can't wander off behind the dimmed layer.
  3. Escape closes it, and so does a visible close button with an accessible name such as aria-label="Close".
  4. Focus goes back to the button that opened it, so the visitor doesn't land at the top of the page.

On top of that, the modal needs a role and a name: role="dialog" with aria-modal="true", and aria-labelledby pointing at its heading. The native <dialog> element opened with showModal() gives you the role, the inert page, the Escape key and the focus move for free; MDN's dialog reference lists what the browser handles.

The close button matters for more than screen readers. In Popupsmart's 2026 benchmark, 40.5% of popup displays end with the visitor closing the popup (all displays pooled, February 2025 - September 2026, since close tracking began), and 71% of visitors who close a popup do so within 5 seconds of it appearing. Closing is the most common thing people do with a popup, and they decide fast.

Warning
Red Flag: A modal without Escape or a visible close button traps keyboard users on your page. Bootstrap's data-bs-keyboard="false" and a CSS-only modal both remove Escape, so add another clear way out.

Bootstrap Modal Popup

A modal asks the visitor to act before moving on, whether that means reading an alert or handing over some information.

Bootstrap's modal plugin builds modal popups and dialog boxes from a handful of classes. The example below shows how you can create your own modal popup with a header, footer and message body. The code is written for Bootstrap 5.3 (5.3.8 at the time of writing), which runs without jQuery.

<!-- In the <head> -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"
  integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">

<!-- The button that opens the modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModal">
  Open the modal
</button>

<!-- The modal -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h2 class="modal-title fs-5" id="myModalLabel">Confirmation</h2>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <p>Do you want to save changes you made to document before closing?</p>
        <p class="text-warning"><small>If you don't save, your changes will be lost.</small></p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

<!-- Before </body> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
  integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>

The button opens the modal with no JavaScript of your own. Bootstrap adds role="dialog" and aria-modal="true" when it opens, keeps focus inside, closes it on Escape, on a backdrop click and on any element with data-bs-dismiss="modal", and returns focus to the button when it closes.

Image of Bootstrap modal popup with a Confirmation title and Close and Save changes buttons

To open it without a click, add this after the Bootstrap script. The modal opens by itself as soon as the browser has loaded the page's “document object model”:

<script>
  document.addEventListener("DOMContentLoaded", () => {
    const modal = new bootstrap.Modal("#myModal");
    modal.show();
  });
</script>
Info
By the Numbers: Popups that wait before appearing convert 0.83% vs 0.61% for popups shown the instant the page loads (median campaign); the direction holds in every year of data but the difference is not statistically reliable, so treat it as a lean, not a rule. (Popupsmart popup benchmark 2026)

Three more options cover most real projects:

  • Focus a field when the modal opens. The HTML autofocus attribute has no effect inside a Bootstrap modal, so listen for Bootstrap's shown.bs.modal event and call focus() on the input.
  • Force an answer. data-bs-backdrop="static" stops a backdrop click from closing the modal. Add data-bs-keyboard="false" only if the modal really can't be dismissed, such as an unsaved-changes warning, and keep the close button.
  • Long content. Add modal-dialog-scrollable next to modal-dialog-centered so the body scrolls inside the modal.
const myModal = document.getElementById("myModal");
const myInput = document.getElementById("myInput");

myModal.addEventListener("shown.bs.modal", () => {
  myInput.focus();
});

If you're upgrading an old Bootstrap 3 or 4 modal, these are the changes that break it:

Bootstrap 3 and 4 (jQuery) Bootstrap 5.3
data-toggle="modal", data-target data-bs-toggle="modal", data-bs-target
data-dismiss="modal" data-bs-dismiss="modal"
<button class="close">×</button> <button class="btn-close" aria-label="Close"></button>
btn-default btn-secondary
$('#myModal').modal('show') bootstrap.Modal.getOrCreateInstance('#myModal').show()

For the whole component, from sizes and fullscreen modals to forms inside a modal, read our Bootstrap popup guide and the official Bootstrap 5.3 modal documentation.

HTML dialog modal popup (vanilla JavaScript)

The native <dialog> element is the simplest correct way to build a modal popup in 2026: no library, and the browser handles the hard parts. Call showModal() and the page behind becomes inert, focus moves inside, and Escape closes it. When it closes, browsers send focus back to the element that was focused before it opened.

<button type="button" id="open-offer">Get the offer</button>

<dialog id="offer" class="modal" aria-labelledby="offer-title">
  <div class="modal-box">
    <h2 id="offer-title">Get free shipping on your first order</h2>
    <p>Join our list and we'll email you the code.</p>

    <form action="/subscribe" method="post">
      <label for="offer-email">Email address</label>
      <input id="offer-email" name="email" type="email" autocomplete="email" required autofocus>
      <button type="submit">Send my code</button>
    </form>

    <form method="dialog">
      <button type="submit" class="modal-close" aria-label="Close">&times;</button>
    </form>
  </div>
</dialog>

<script>
  const offer = document.getElementById("offer");

  document.getElementById("open-offer").addEventListener("click", () => {
    offer.showModal();
  });

  // A click on the dimmed backdrop lands on the <dialog> itself, not on .modal-box
  offer.addEventListener("click", (event) => {
    if (event.target === offer) offer.close();
  });
</script>
.modal {
  padding: 0;
  border: 0;
  border-radius: 12px;
  width: calc(100% - 2rem);
  max-width: 28rem;
}
.modal::backdrop {
  background: rgb(0 0 0 / 0.5);
}
.modal-box {
  position: relative;
  padding: 1.5rem;
}
.modal-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  font-size: 1.5rem;
  line-height: 1;
}
/* Stop the page behind from scrolling while the modal is open */
body:has(dialog[open]) {
  overflow: hidden;
}

How the pieces work:

  • <form method="dialog"> closes the dialog when its button is pressed, with no JavaScript.
  • autofocus on the email field puts the cursor where the visitor is meant to type. MDN recommends it on the element the visitor should use first.
  • The inner .modal-box carries the padding. Without it, a click on the popup's own padding would also count as a click on the dialog and close it.
  • ::backdrop styles the dimmed layer the browser draws behind the dialog.

Newer browsers also support closedby="any" on the <dialog>, which closes it on a backdrop click without the script. Until it works in every browser your visitors use, keep the click listener.

Keep the form short. Popups asking for one or two fields convert 0.88% and 0.94%, against 0.56% for three fields (median campaign; spin-to-win and other gamified popups are counted separately).

Tip
Key Takeaway: Use showModal(), not show(). show() opens the same element as a non-modal dialog: no backdrop, no inert page, and Escape does nothing.

The same element also works for a popup that opens on a button click; that guide covers on-click popups in more depth.

jQuery Modal Popup

Careful
Legacy code: Use this only on a site that already loads jQuery. On a new site, the <dialog> version above does more with less code, and Bootstrap 5 no longer needs jQuery at all.

A jQuery modal dialog box shows information quickly. Set it up with care and it can alert your users or show them errors, the job of any contemporary modal.

Here's the jQuery example. It works with jQuery 3.x and 4.0. jQuery doesn't give you any of the four accessibility behaviours, so the script adds them: it remembers the button that opened the modal, makes the page behind inert, closes on Escape and on a backdrop click, and puts focus back when it closes. The page content has to sit inside <main>, with the modal outside it, for inert to work.

<main>
  <h2>This is a heading</h2>
  <p>This is a paragraph.</p>
  <p>This is another paragraph.</p>
  <button type="button" id="open-modal">Click me</button>
</main>

<div id="modal" class="jq-modal" role="dialog" aria-modal="true" aria-labelledby="modal-title" hidden>
  <div class="jq-modal-box">
    <h2 id="modal-title">Modal title</h2>
    <p>This modal popup opened with jQuery.</p>
    <button type="button" class="jq-modal-close">Close</button>
  </div>
</div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"
  integrity="sha384-fgGyf7Mo7DURSOMnOy7ed+dkq5Job205Gnzu6QIg0BOHKaqt4D76Dt8VlDCzcMHV" crossorigin="anonymous"></script>
<script>
$(function () {
  var $modal = $("#modal");
  var $opener = null;

  function openModal() {
    $opener = $(document.activeElement);
    $modal.prop("hidden", false);
    $("main").attr("inert", "");
    $modal.find("button, [href], input, select, textarea").first().trigger("focus");
  }

  function closeModal() {
    $modal.prop("hidden", true);
    $("main").removeAttr("inert");
    if ($opener) $opener.trigger("focus");
  }

  $("#open-modal").on("click", openModal);
  $modal.on("click", ".jq-modal-close", closeModal);
  $modal.on("click", function (event) {
    if (event.target === this) closeModal();
  });
  $(document).on("keydown", function (event) {
    if (event.key === "Escape" && !$modal.prop("hidden")) closeModal();
  });
});
</script>
.jq-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / 0.5);
}
/* display: grid would override the hidden attribute, so restate it */
.jq-modal[hidden] {
  display: none;
}
.jq-modal-box {
  width: calc(100% - 2rem);
  max-width: 28rem;
  padding: 1.5rem;
  border-radius: 8px;
  background: #fff;
}

After this, clicking the button dims the page and opens the modal; Escape, the Close button or a click on the dimmed area closes it. If you're moving an old site to jQuery 4, the jQuery 4.0 upgrade guide lists the removed methods.

CSS Modal Popup

CSS is a language that describes how the HTML elements are to be displayed on screen. So the HTML comes first, then the CSS.

A CSS-only modal uses the :target pseudo-class: the link changes the URL to #open-modal, and the CSS shows the element with that id.

<div class="container">
  <div class="interior">
    <a class="btn" href="#open-modal">Basic CSS-Only Modal</a>
  </div>
</div>
<div id="open-modal" class="modal-window" role="dialog" aria-labelledby="open-modal-title">
  <div>
    <a href="#" title="Close" class="modal-close">Close</a>
    <h1 id="open-modal-title">Hello!</h1>
    <div>A CSS-only modal based on the :target pseudo-class. Hope you find it helpful.</div>
  </div>
</div>

Then add the CSS. The nesting below (&:target, & > div) is native CSS nesting, which every current browser supports, so it no longer needs Sass.

.modal-window {
  position: fixed;
  background-color: rgba(255, 255, 255, 0.25);
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 999;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.3s, visibility 0.3s;
  &:target {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }
  & > div {
    width: 400px;
    max-width: calc(100% - 2rem);
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 2em;
    background: #ffffff;
    color: #333333;
  }
  & header {
    font-weight: bold;
  }
  & h1 {
    font-size: 150%;
    margin: 0 0 15px;
    color: #333333;
  }
}

.modal-close {
  color: #333333;
  line-height: 50px;
  font-size: 80%;
  position: absolute;
  right: 0;
  text-align: center;
  top: 0;
  width: 70px;
  text-decoration: none;
  &:hover {
    color: #000;
  }
}

/* Demo Styles */

html,
body {
  height: 100%;
}

body {
  font: 600 18px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  background-color: #f69d75;
  color: #555555
}

a {
  color: inherit;
}

.container {
  display: grid;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.btn {
  background-color: #fff;
  padding: 1em 1.5em;
  border-radius: 3px;
  text-decoration: none;
}

It looks like this:

Example of CSS modal popup with a Hello heading, a short message and a Close link

Two changes from the original version of this example matter: visibility: hidden keeps the closed modal's Close link out of the Tab order (opacity alone left it focusable), and the transition names its properties instead of all.

Careful
Common Mistake: Shipping a :target modal as a signup popup. It can't move focus inside, keep Tab in, or close on Escape, and it adds a history entry, so the Back button reopens it. Use it for demos; use <dialog> for real visitors.

Tailwind CSS modal popup

Tailwind CSS doesn't ship a modal component: you style one with utility classes. The cleanest base is the same <dialog> element, which gives you focus handling and Escape without extra JavaScript. The example below is written for Tailwind CSS v4 (4.3 at the time of writing). The Play CDN script in the first line is for trying it out; in production, install Tailwind with your build tool.

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

<button id="open-tw-modal" type="button"
  class="rounded-lg bg-blue-600 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600">
  Get the offer
</button>

<dialog id="tw-modal" aria-labelledby="tw-modal-title"
  class="m-auto w-[calc(100%-2rem)] max-w-md rounded-xl bg-white p-0 shadow-xl backdrop:bg-black/50">
  <div class="relative p-6">
    <h2 id="tw-modal-title" class="pr-8 text-xl font-semibold text-gray-900">
      Get free shipping on your first order
    </h2>
    <p class="mt-2 text-gray-700">Join our list and we'll email you the code.</p>

    <form class="mt-5 space-y-3" action="/subscribe" method="post">
      <label for="tw-email" class="block text-sm font-medium text-gray-900">Email address</label>
      <input id="tw-email" name="email" type="email" autocomplete="email" required autofocus
        class="w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 focus:border-blue-600 focus:ring-2 focus:ring-blue-600/30 focus:outline-none">
      <button type="submit"
        class="w-full rounded-lg bg-blue-600 px-4 py-2.5 font-medium text-white hover:bg-blue-700">
        Send my code
      </button>
    </form>

    <form method="dialog">
      <button type="submit" aria-label="Close"
        class="absolute top-3 right-3 rounded-md p-1 text-gray-700 hover:bg-gray-100 focus-visible:outline-2 focus-visible:outline-blue-600">
        <span aria-hidden="true" class="block text-2xl leading-none">&times;</span>
      </button>
    </form>
  </div>
</dialog>

<script>
  const twModal = document.getElementById("tw-modal");

  document.getElementById("open-tw-modal").addEventListener("click", () => {
    twModal.showModal();
  });

  twModal.addEventListener("click", (event) => {
    if (event.target === twModal) twModal.close();
  });
</script>

The classes that make it a modal:

  • m-auto centres the dialog. Tailwind's Preflight sets margin: 0 on every element, which removes the browser's own centring of <dialog>; without m-auto the modal sticks to the top-left corner. This is the most common reason a Tailwind modal "doesn't work".
  • backdrop:bg-black/50 styles the dimmed layer through the backdrop: variant, which targets the ::backdrop pseudo-element (Tailwind's variants reference lists it).
  • w-[calc(100%-2rem)] max-w-md keeps a margin on phones and caps the width on desktop.
  • relative p-6 on the inner wrapper holds the padding, so a click on the popup's edge doesn't count as a backdrop click, and anchors the absolute close button.

On Tailwind v3.1 or later the same markup works with one change: v3's outline-2 sets only the width, so write focus-visible:outline focus-visible:outline-2 on the two buttons. The backdrop: variant arrived in v3.1; on older versions, style dialog::backdrop in your CSS file.

Note
Quick Insight: Tailwind UI kits often build modals from plain <div>s with a fixed overlay. They look the same, but you then owe the focus trap, Escape and the inert page yourself. Starting from <dialog> gets those from the browser.

Frameworks change where the state lives, not what a modal has to do. In React, keep an isOpen state and call showModal() on a <dialog> ref when it turns true; in Vue 3, do the same with a template ref and <Teleport to="body"> so the modal isn't trapped inside a parent with overflow: hidden or its own stacking context. Step-by-step code for both is in our React popup tutorial and our Vue modal and popup guide. On WordPress, the WordPress popup without a plugin guide shows where the code goes in a theme.

What Do We Recommend? Popupsmart: A Simple Popup Creator Service

You can hand-code a modal popup for any purpose and put it anywhere on your page. There's also a simpler route.

Popupsmart is a smart popup builder that does the building for you. Start by deciding what the popup is for: to increase sales conversion, grow an email list or increase phone calls. Once you've picked a goal, move on to these steps:

Add Popupsmart's embed code once (no code after that)

If you're a marketer rather than a developer, you don't need any of the code above. Popupsmart adds popups to your site through one embed code, pasted once:

  1. Sign up (Popupsmart has a free plan at $0) and click Embed Code in the left bar of the dashboard.
  2. Copy the code. It looks like this, with your own account ID in data-id:
<script src="https://cdn.popupsmart.com/bundle.js" data-id="YOUR_ACCOUNT_ID" async defer></script>
  1. Paste it just before the closing </body> tag of your site's template, or add it through Google Tag Manager or your CMS. Add it once per site.
  2. Add and verify your domain under Websites, then design your modal and publish it.

From then on, every new modal, slide-in or bar is built and published in the dashboard, with no new code. How to embed the code on your site in the help center has the details for each platform. To open a Popupsmart modal from your own button instead of a timer, use On-Click Targeting, covered in our guide to a popup that opens on a button click.

Popupsmart’s Design

You start from a ready-made template. To guide your audience with an “Announcement Popup”, you could pick this one:

Modal popup example from Popupsmart: an announcement popup template

Or if you want to increase sales conversion with a “Product Promotion Popup”, it could look like this:

Modal popup for promotion: a product promotion popup template from Popupsmart

You can browse more of them in our popup templates.

Popupsmart’s Display

You can tailor the message to what the visitor does on your site, which helps conversion, engagement and sales. Popupsmart's one embed code works on any site where you can add a script, whatever platform it's built on.

Modal popup example for sales, made with Popupsmart

Popupsmart’s Integration System

Once you've chosen a goal and a template that fits it, you customize the popup and publish it from the Popupsmart dashboard. You don't touch code at any point.

Info
Pro Tip: Whichever way you build it, test the modal with the keyboard alone: open it, Tab through it, press Escape, and check where focus lands. It takes a minute and catches most accessibility bugs.

Frequently Asked Questions

What is a modal popup?

A modal popup is a dialog box that opens on top of a web page and blocks the page behind it until the visitor answers or closes it. Keyboard focus moves into the popup, the page behind it can't be clicked, and the popup closes with a close button or the Escape key.

What is the difference between a modal and a popup?

Popup is the umbrella word for anything that appears over a page. A modal is the kind that blocks the page until the visitor responds. A non-modal popup, such as a slide-in box, a sticky bar or a toast, leaves the page usable while it's open.

Do I still need jQuery for a Bootstrap modal?

No. Bootstrap 5 dropped jQuery. The modal runs on Bootstrap's own JavaScript bundle: use data-bs-toggle and data-bs-target on the button, or new bootstrap.Modal('#myModal').show() in plain JavaScript. The data-toggle and $('#myModal').modal('show') syntax belongs to Bootstrap 4 and earlier.

How do I make a modal popup accessible?

Move keyboard focus into the modal when it opens, keep Tab inside it while it's open, close it with Escape and with a visible close button, and send focus back to the button that opened it. Give the modal a name with aria-labelledby. The HTML dialog element opened with showModal() does most of this for you.

How do I close a modal popup when the visitor clicks outside it?

Bootstrap closes on a backdrop click by default. With the HTML dialog element, listen for clicks on the dialog and close it when event.target is the dialog itself, which happens when the click lands on the backdrop. Keep the content in an inner wrapper with the padding, so clicks on the popup's own edge don't count.

How do I make a modal popup with Tailwind CSS?

Use the HTML dialog element, style it with utility classes and open it with showModal(). Add m-auto, because Tailwind's Preflight sets margin: 0 on every element and removes the browser's centring, and style the dimmed layer with the backdrop: variant, for example backdrop:bg-black/50.

Can I open a modal popup when the page loads?

Yes. In Bootstrap 5 call new bootstrap.Modal('#myModal').show() once the page is ready; with the dialog element call showModal(). Popupsmart's 2026 benchmark found that popups that wait before appearing convert 0.83% vs 0.61% for popups shown the instant the page loads (median campaign), but the difference is not statistically reliable, so treat it as a lean, not a rule.

Can I create a modal popup without writing code?

Yes. A popup builder such as Popupsmart lets you design the modal, choose when it appears and who sees it, and add it to your site with one embed code. Popupsmart has a free plan at $0.

Reviewed by Mert Özeren