Skip to main content

Last updated: March 13, 2026

How to Create a Modal with CSS (4 Methods)

The complete guide to building modals and popups. Learn pure CSS methods and the modern dialog element with interactive examples.

Understanding CSS Modals

A modal (or dialog) is a UI pattern that displays content in a layer above the main page. The challenge is managing the open/closed state without JavaScript. CSS offers several techniques, each with trade-offs.

Pure CSS Approaches

Use :target selector, checkbox toggle, or :focus-within to control modal visibility without JavaScript. Trade-off: accessibility limitations.

Modern Best Practice

The native <dialog> element provides built-in accessibility, ESC key support, focus trapping, and backdrop styling with minimal JS.

Pro tip: For production apps, always prefer the dialog element. Pure CSS methods are great for learning but lack proper accessibility features.

Quick Reference

Compare the different modal methods to choose the right one for your project.

:target

Pure CSS:Yes
Accessibility:Limited
Browser Support:99%+

CheckboxRecommended

Pure CSS:Yes
Accessibility:Moderate
Browser Support:99%+

Focus-within

Pure CSS:Yes
Accessibility:Limited
Browser Support:95%+

DialogRecommended

Pure CSS:Minimal JS
Accessibility:Excellent
Browser Support:96%+
1

:target Selector Method

Uses URL hash fragments to show and hide the modal. When a link points to #modal, the :target pseudo-class activates the modal styles. Clean and simple, but changes the URL.

Live Preview

Pure CSSLimited A11y

Full Code

Pros

  • +Pure CSS - no JavaScript needed
  • +Simple and easy to understand
  • +Works with browser back button
  • +Good browser support

Cons

  • -Changes the URL (adds #modal)
  • -Limited accessibility (no ESC key)
  • -Can interfere with page navigation
  • -Scrolls to top when closed

When to Use

  • *Simple landing pages
  • *When JavaScript is not available
  • *Quick prototypes
  • *When URL history is acceptable
2

Checkbox Toggle Method

Recommended

Uses a hidden checkbox to maintain modal state. The label acts as a trigger button, and the :checked pseudo-class controls visibility. The most reliable pure CSS method.

Live Preview

Pure CSSModerate A11y

Full Code

Pros

  • +Pure CSS - no JavaScript needed
  • +Doesn't change the URL
  • +Click overlay to close
  • +Maintains state properly
  • +Easy to style and animate

Cons

  • -No ESC key support without JS
  • -Slightly more complex HTML structure
  • -Labels instead of buttons (semantic concern)
  • -Can't trap focus inside modal

When to Use

  • *When you need pure CSS solution
  • *Simple confirmation dialogs
  • *Image galleries
  • *Forms that don't require accessibility
3

:focus-within Method

Uses the :focus-within pseudo-class to show the modal when any focusable element inside it has focus. Creative but has limitations with closing behavior.

Live Preview

Pure CSSLimited A11y

Full Code

Pros

  • +Pure CSS solution
  • +No URL changes
  • +Closes when focus leaves modal
  • +Works with keyboard navigation

Cons

  • -Unpredictable closing behavior
  • -Hard to control when it closes
  • -Requires manual focus management
  • -Limited browser support vs other methods

When to Use

  • *Dropdown menus
  • *Tooltips with interactive content
  • *When focus-based behavior is acceptable
  • *Experimental projects
4

HTML Dialog Element

Recommended

The native <dialog> element is the modern, accessible way to create modals. It requires minimal JavaScript to open/close but provides built-in backdrop, ESC key support, and proper focus management.

Live Preview

Minimal JSExcellent A11y

Full Code

Pros

  • +Built-in accessibility (ESC key, focus trap)
  • +Native ::backdrop pseudo-element
  • +Proper semantic HTML
  • +Works with form submission
  • +Automatic focus management
  • +Best practice approach

Cons

  • -Requires minimal JavaScript to open
  • -Slightly newer browser support
  • -Less styling control than div-based modals
  • -Click-outside-to-close needs JS

When to Use

  • *Production applications
  • *When accessibility matters (always)
  • *Form dialogs and confirmations
  • *Any situation where you can use JS

Modal Styling Tips

1. Centering the Modal

Use position: fixed with inset: 0 and Flexbox centering. This ensures the modal stays centered regardless of scroll position.

.modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

2. Overlay Styling

Create a semi-transparent backdrop. Use backdrop-filter for blur effects. The overlay should cover the entire viewport.

.overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
}

3. Fade & Scale Animation

Combine opacity and transform for smooth open/close animations. Use visibility to properly hide the modal when closed.

.modal {
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
}
.modal.open {
  opacity: 1;
  visibility: visible;
}
.modal-content {
  transform: scale(0.9);
  transition: transform 0.3s;
}
.modal.open .modal-content {
  transform: scale(1);
}

4. Close Button Positioning

Position the close button in the top-right corner of the modal content. Use a large touch target for mobile users.

.close-btn {
  position: absolute;
  top: 12px;
  right: 16px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  cursor: pointer;
}

Preventing Body Scroll (Requires JS)

To prevent the background from scrolling when modal is open, you need JavaScript. Add overflow: hidden to the body when modal opens and remove it when it closes. CSS-only solutions like body:has(.modal:target) have limited browser support.

// When opening modal
document.body.style.overflow = 'hidden';

// When closing modal
document.body.style.overflow = '';

Frequently Asked Questions

What is the best way to create a modal in CSS?

The best approach depends on your requirements. For production applications where accessibility matters, use the native <dialog> element with minimal JavaScript. For pure CSS solutions without JavaScript, the checkbox toggle method is most reliable. The :target selector works but changes the URL, which can cause issues with page navigation.

Can I create a modal with just CSS, no JavaScript?

Yes! You can create modals with pure CSS using the :target selector or checkbox toggle method. However, these approaches have limitations: no ESC key support, no focus trapping, and less control over accessibility. For simple use cases, pure CSS modals work fine, but production applications should use the <dialog> element.

How do I close a modal when clicking outside?

With the checkbox method, wrap the overlay in a label that toggles the checkbox. With the :target method, make the overlay a link to '#'. For the dialog element, add a click listener that checks if the click target is the dialog itself (not its contents) and calls dialog.close().

How do I prevent body scroll when modal is open?

Preventing body scroll requires JavaScript. When the modal opens, add overflow: hidden to the body element. When it closes, remove it. For the dialog element, some browsers handle this automatically. You can also use CSS with body:has(.modal:target) { overflow: hidden; } but browser support is limited.

How do I animate a CSS modal?

Use CSS transitions on the modal container. Animate opacity (0 to 1) and transform (scale or translateY). Set visibility: hidden with opacity: 0 for the closed state, then visibility: visible with opacity: 1 for open. The transition property handles the animation. For dialog elements, use the [open] attribute selector.