CSS Media Queries

Create responsive designs with CSS media queries

Introduction to Media Queries

Media queries allow you to apply CSS styles based on device characteristics such as screen width, height, orientation, and more. They are a fundamental tool for creating responsive designs that adapt to different devices and viewport sizes.

@media [media-type] [and (media-feature)] { /* CSS rules to apply when media query matches */ }

Common media types include screen, print, and all. Media features include width, height, orientation, resolution, and more.

Basic Media Query Example

This box changes color based on your viewport width. Resize your browser window to see the effect.

Viewport Width Demo

Current color indicates viewport width range:

  • Red: < 576px (Extra small)
  • Orange: 577px - 768px (Small)
  • Green: 769px - 992px (Medium)
  • Blue: > 993px (Large)
/* Default style */ .media-query-demo { background-color: #5e72e4; /* Blue */ } /* Extra small devices (phones) */ @media (max-width: 576px) { .media-query-demo { background-color: #ea5455; /* Red */ } } /* Small devices (tablets) */ @media (min-width: 577px) and (max-width: 768px) { .media-query-demo { background-color: #ff9f43; /* Orange */ } } /* Medium devices (small laptops) */ @media (min-width: 769px) and (max-width: 992px) { .media-query-demo { background-color: #28c76f; /* Green */ } }

Responsive Layout

Media queries are often used with flexible layouts (like Flexbox or Grid) to create responsive designs. This example uses Flexbox with flex-wrap to create a responsive layout.

Item 1
Item 2
Item 3
.responsive-layout { display: flex; flex-wrap: wrap; gap: 20px; } .responsive-layout-item { flex: 1; min-width: 200px; /* Forces wrap on smaller screens */ }

Responsive Grid

This example shows how to create a responsive grid layout using CSS Grid and media queries. The number of columns changes based on the viewport width.

Item 1
Item 2
Item 3
Item 4
.responsive-grid { display: grid; grid-template-columns: repeat(1, 1fr); /* 1 column by default */ gap: 20px; } /* Small devices (tablets) */ @media (min-width: 576px) { .responsive-grid { grid-template-columns: repeat(2, 1fr); /* 2 columns */ } } /* Large devices (desktops) */ @media (min-width: 992px) { .responsive-grid { grid-template-columns: repeat(4, 1fr); /* 4 columns */ } }

Responsive Typography

You can create responsive typography using viewport units (vw, vh) or with media queries. This example uses a combination of both approaches.

This heading uses viewport units

This paragraph also scales with the viewport size. Resize your browser to see how the text size adjusts automatically. This approach creates a smooth scaling effect without breakpoints.

.responsive-typography h2 { font-size: calc(1.5rem + 1vw); } .responsive-typography p { font-size: calc(0.9rem + 0.3vw); line-height: 1.6; }

Orientation Media Query

Media queries can detect the orientation of the device (portrait or landscape). This is particularly useful for mobile devices.

Orientation Demo

This box changes color based on your device orientation.

.orientation-demo { background-color: #5e72e4; /* Blue for landscape */ } .orientation-demo::after { content: "Current orientation: Landscape"; } @media (orientation: portrait) { .orientation-demo { background-color: #ea5455; /* Red for portrait */ } .orientation-demo::after { content: "Current orientation: Portrait"; } }

Hover Capability Detection

The hover media feature detects whether the user's primary input mechanism can hover over elements. This is useful for creating different experiences for touch devices vs. mouse-based devices.

Hover Capability Demo

.hover-demo::after { content: "Hover capability not detected"; } @media (hover: hover) { .hover-demo::after { content: "Hover capability detected - Try hovering me!"; } .hover-demo:hover { transform: scale(1.05); background-color: #7460ee; } }

Dark Mode Detection

The prefers-color-scheme media feature detects if the user has requested a light or dark color theme. This allows you to provide a dark mode version of your site.

Dark Mode Preference Demo

This box adapts to your system's color scheme preference.

.dark-mode-demo { background-color: white; color: #333; border: 1px solid #ddd; } .dark-mode-demo::after { content: "Light mode detected"; } @media (prefers-color-scheme: dark) { .dark-mode-demo { background-color: #333; color: white; border-color: #555; } .dark-mode-demo::after { content: "Dark mode detected"; } }

Reduced Motion Preference

The prefers-reduced-motion media feature detects if the user has requested minimized animations. This is an important accessibility feature for users who experience motion sickness or distractions from animations.

Motion Preference Demo

This box animates unless you've enabled reduced motion in your system settings.

.motion-demo { animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @media (prefers-reduced-motion: reduce) { .motion-demo { animation: none; /* Disable animation */ } }

Responsive Navigation

A common use case for media queries is creating responsive navigation menus that transform into mobile-friendly versions on smaller screens.

/* Desktop navigation */ .responsive-nav-items { display: flex; } .responsive-nav-toggle { display: none; /* Hidden on desktop */ } /* Mobile navigation */ @media (max-width: 768px) { .responsive-nav-items { flex-direction: column; display: none; /* Hidden by default */ } .responsive-nav-items.active { display: flex; /* Shown when active */ } .responsive-nav-toggle { display: block; /* Visible on mobile */ } }

Container Queries (Simulated)

Container queries allow you to style elements based on the size of their container rather than the viewport. This example simulates container queries using JavaScript and regular media queries.

Small Container

Content adapts to container width

Medium Container

Content adapts to container width

Large Container

Content adapts to container width
/* Container query simulation using classes */ .container-query-demo.small .container-item { background-color: #ea5455; /* Red */ } .container-query-demo.medium .container-item { background-color: #ff9f43; /* Orange */ } .container-query-demo.large .container-item { background-color: #28c76f; /* Green */ } /* In a real container query, it would look like: */ @container (max-width: 300px) { .container-item { background-color: #ea5455; } }

Print Media Query

The print media type allows you to define styles specifically for when the page is printed. Try using your browser's print preview to see how this page would look when printed.

/* Screen styles */ .print-demo { background-color: #5e72e4; color: white; } /* Print styles */ @media print { .print-demo { background-color: white !important; color: black !important; border: 1px solid #ddd; } .print-demo::after { content: " (Optimized for printing)"; } /* Hide elements not needed for print */ .responsive-nav, .hover-demo, .motion-demo { display: none !important; } }

Media Query Best Practices

  • Mobile-First Approach: Start with styles for mobile devices and then add media queries for larger screens using min-width.
  • Use Logical Operators: Combine media features with and, not, and only for more specific targeting.
  • Common Breakpoints: While you should design for your content, common breakpoints are around 576px, 768px, 992px, and 1200px.
  • Test on Real Devices: Always test your responsive designs on actual devices, not just browser resizing.
  • Accessibility: Use media queries like prefers-reduced-motion and prefers-color-scheme to enhance accessibility.
  • Performance: Be mindful of the CSS you load on mobile devices. Consider using media queries to load lighter resources on smaller screens.
/* Example of combining media features */ @media screen and (min-width: 768px) and (orientation: landscape) { /* Styles for landscape tablets and larger */ } /* Example of using 'not' */ @media not screen and (min-width: 768px) { /* Styles for everything except screens 768px and wider */ }