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.
| Method | Pure CSS | Accessibility | Browser Support |
|---|---|---|---|
| :target | Yes | Limited | 99%+ |
| CheckboxRecommended | Yes | Moderate | 99%+ |
| Focus-within | Yes | Limited | 95%+ |
| DialogRecommended | Minimal JS | Excellent | 96%+ |
:target
CheckboxRecommended
Focus-within
DialogRecommended
: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
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
Checkbox Toggle Method
RecommendedUses 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
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
: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
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
HTML Dialog Element
RecommendedThe 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
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
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.
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.
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().
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.
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.
More CSS Tutorials
Copy CSS from Website
Extract styles with 2 clicks
Center a Div (CSS)
Flexbox, Grid, and more
Center a Div (Tailwind)
Utility classes for centering
Convert CSS to Tailwind
CSS to utility classes
Glassmorphism Effect
Frosted glass UI style
Neumorphism Button
Soft UI button design
Responsive Navbar
Mobile-friendly navigation
Sticky Header
Fixed navigation on scroll
CSS Pagination
Page navigation styles
CSS Accordion
Expandable content sections
Dropdown Menu
Hover and click dropdowns
Toast Notifications
Animated alert messages
Hamburger Menu
Animated menu icon
Animate Gradients
Moving gradient backgrounds
Skeleton Loader
Loading placeholder UI
Element Screenshot
Capture any element as image
Pick Color from Website
Eyedropper tool comparison
Identify Fonts
Find fonts on any website
Download All Images
Bulk save images from any site
Measure Elements
Page ruler and measurements
Extract Colors from Website
Get any color palette instantly
Dark Mode Toggle
CSS variables and localStorage
Responsive Grid
CSS Grid auto-fit and minmax
Center Text in CSS
text-align, Flexbox, and Grid
Make Text Bold
font-weight values explained
Add Shadow in CSS
box-shadow, text-shadow, drop-shadow
Round Corners in CSS
border-radius and pill shapes
Style File Input
Custom upload buttons
