Animated Accessible Modal In Pure JavaScript – microModal

Category: Javascript , Modal & Popup | June 3, 2026
Authormicromodal
Last UpdateJune 3, 2026
LicenseMIT
Tags
Views3,834 views
Animated Accessible Modal In Pure JavaScript – microModal

Micromodal.js is a dependency-free JavaScript modal library that creates accessible dialog windows with ARIA state management, focus trapping, overlay dismissal, and keyboard close behavior.

It helps you build modern and performant modal UI for confirmations, signup forms, alerts, onboarding steps, product notices, and dashboard panels.

Note that Micromodal.js does not ship any CSS styles. You control the modal layout, overlay, animation, spacing, and theme through CSS, while the script handles modal behavior and accessibility state.

Features:

  • Toggle ARIA visibility state.
  • Close dialogs on overlay clicks.
  • Close dialogs with the Escape key.
  • Trap keyboard focus inside dialogs.
  • Restore focus after closing.
  • Support nested dialog stacks.
  • Accept custom trigger attributes.

Use Cases:

  • Signup modals show a form over the current page.
  • Confirmation dialogs protect destructive dashboard actions.
  • Product detail popups keep users inside a listing page.
  • Onboarding dialogs explain one step before interaction continues.

How to use it:

1. Install microModal. The library works through npm, Yarn, CDN scripts, or a direct browser download.

# Yarn
$ yarn add micromodal
# NPM
$ npm install micromodal
<!-- jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/npm/micromodal/dist/micromodal.min.js"></script>
<!-- unpkg CDN -->
<script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>

2. Import the package as an ES module or CommonJS module.

// ES module import for bundlers.
import MicroModal from 'micromodal';
// CommonJS import for older build setups.
var MicroModal = require('micromodal');

3. Place modal markup near the closing body tag when the overlay should cover the full viewport. The trigger value must match the modal ID.

<button data-micromodal-trigger="signup-dialog">
  Open signup dialog
</button>
<div class="modal" id="signup-dialog" aria-hidden="true">
  <div class="modal__overlay" tabindex="-1" data-micromodal-close>
    <div
      class="modal__container"
      role="dialog"
      aria-modal="true"
      aria-labelledby="signup-dialog-title"
    >
      <header class="modal__header">
        <h2 id="signup-dialog-title">Join the early access list</h2>
        <!-- This element closes the modal. -->
        <button
          class="modal__close"
          type="button"
          aria-label="Close signup dialog"
          data-micromodal-close
        >
          ×
        </button>
      </header>
      <div class="modal__content">
        <label for="signup-email">Email address</label>
        <input id="signup-email" type="email" autocomplete="email">
      </div>
    </div>
  </div>
</div>

4. Initialize MicroModal and done.

// Bind all elements that use the default trigger attribute.
MicroModal.init();

5. Add your own CSS to the modal window. Micromodal.js adds the open class, but your stylesheet must define how the modal appears.

.modal {
  display: none;
}
.modal.is-open {
  display: block;
}

6. All configuration options.

  • onShow (function): Runs when a modal opens. The function receives the modal element, the previously focused element, and the event or trigger context.
  • onClose (function): Runs when a modal closes. The function receives the modal element, the previously focused element, and the event or trigger context.
  • openTrigger (string): Sets the data attribute used to open modals. The default value is data-micromodal-trigger.
  • closeTrigger (string): Sets the data attribute used to close modals. The default value is data-micromodal-close.
  • openClass (string): Sets the class added to the modal when it opens. The default value is is-open.
  • disableScroll (boolean): Locks body scrolling while a modal stays open. The default value is false.
  • disableFocus (boolean): Turns off automatic focus on the first focusable element inside the modal. The default value is false.
  • awaitOpenAnimation (boolean): Waits for the open animation to finish before focus moves inside the modal. The default value is false.
  • awaitCloseAnimation (boolean): Waits for the close animation to finish before the open class leaves the modal. The default value is false.
  • debugMode (boolean): Controls diagnostic warnings for missing IDs and trigger problems. The default value is false.
MicroModal.init({
  // options here
});

7. API methods.

// Bind modal triggers found through the configured open attribute.
MicroModal.init({
  disableScroll: true
});
// Create and register a modal instance for an element or ID.
MicroModal.initModal('account-login-dialog', {
  openClass: 'is-open'
});
// Update configuration for an existing modal instance.
MicroModal.config('account-login-dialog', {
  disableFocus: false
});
// Open a modal by ID.
MicroModal.show('account-login-dialog');
// Open a modal by ID with configuration for this call.
MicroModal.show('account-login-dialog', {
  onShow: function (modal) {
    console.info(modal.id + ' opened');
  }
});
// Close a specific modal by ID.
MicroModal.close('account-login-dialog');
// Close the topmost active modal when nested modals exist.
MicroModal.close();
// Close every active modal instance.
MicroModal.closeAll();
// Remove a registered modal instance and its trigger listeners.
MicroModal.removeModal('account-login-dialog');

8. Callback functions.

MicroModal.init({
  // Runs when a modal opens.
  onShow: function (modal, trigger) {
    console.log('Opened modal:', modal.id);
    console.log('Previous focus or trigger:', trigger);
  },
  // Runs when a modal closes.
  onClose: function (modal, trigger) {
    console.log('Closed modal:', modal.id);
    console.log('Returned focus target:', trigger);
  }
});

Alternatives:

Changelog:

v0.7.0 (06/03/2026)

  • Added MicroModal.closeAll() to close all open modals at once
  • Added MicroModal.initModal() to register a modal dynamically after init()
  • Added MicroModal.removeModal() to unregister a modal and clean up its event listeners
  • Added MicroModal.config() to reconfigure a modal after initialization
  • Support for nested (layered) modals – Esc closes only the topmost
  • Setting role=”alertdialog” on a modal now disables Esc to close
  • keydown listeners are now scoped to each modal element instead of document
  • Close trigger detection now uses closest() for reliable nested element handling
  • show(id, config) reuses existing modal instances; config passed to show() persists on the modal
  • Config passed to init() now applies to all subsequent show() calls
  • Added touchAction: none to scroll lock for iOS momentum scroll

v0.6.2 (05/31/2026)

  • Bugfixes

v0.6.1 (03/22/2025)

  • Add ability to pass an element to Micromodal.close()

v0.5.2 (03/18/2025)

  • Fixed bugs

v0.4.10 (11/28/2020)

  • Fixed bugs

v0.4.9 (11/24/2020)

  • Fixed bugs

v0.4.7 (11/23/2020)

  • Fixed bugs

v0.4.6 (03/27/2020)

  • Removed focus error when no focusable element exists in the modal

v0.4.5 (03/26/2020)

  • Bugs fixed

v0.4.4 (03/26/2020)

  • Added ability to customize open class name

v0.4.3 (03/25/2020)

  • Finds a focusable element which is not the close button on modal open
  • Handle events cleanup if modals are not closed properly
  • The original trigger event is now passed to the onShow and onClose methods
  • Bugs fixed

v0.4.2 (02/25/2020)

  • Add dist files into the zip.

v0.4.1 (09/05/2018)

  • FEATURE A flag to awaitOpenAnimation before focusing on element in modal.
  • FEATURE Passing actual node as second argument to onShow.
  • BUGFIX Fixed issue where active element was undefined.
  • BUGFIX Fixed issue where an opened modal could not be closed by id.

v0.4.0 (05/06/2018)

  • Added abilty to close modals by ID
  • Fixed bug where micromodal would error on initialization
  • Fixed bug where IE crashed due to null reference
  • Fixed bug which didn’t lock modal overlay in IE

v0.3.2 (07/08/2018)

  • BUGFIX Fixed bundling for es and umd builds

You Might Be Interested In:


Leave a Reply