Table of Contents
- What Are Media Queries?
- Core Syntax of Media Queries
- Breakpoints: Defining When Styles Change
- Advanced Media Features
- Implementing Media Queries in Practice
- Best Practices for Effective Media Queries
- Common Pitfalls and How to Avoid Them
- Tools and Resources for Testing Media Queries
- Conclusion
- References
What Are Media Queries?
Media queries are a CSS3 feature that enable styles to be applied dynamically based on the characteristics of the device or environment in which the content is viewed. They act as “conditional statements” for CSS, allowing you to target styles to specific scenarios, such as:
- Screen width/height (e.g., mobile vs. desktop).
- Device orientation (portrait vs. landscape).
- User preferences (e.g., dark mode, reduced motion).
- Device capabilities (e.g., touchscreen, resolution).
In essence, media queries bridge the gap between a static stylesheet and the dynamic needs of modern, multi-device web experiences.
Core Syntax of Media Queries
A media query consists of three main components: media type, media features, and logical operators. The basic syntax is:
@media [media-type] [logical-operator] ([media-feature]: value) {
/* CSS styles to apply */
}
Let’s break down each component.
Media Types
Media types define the category of device the query targets. While early specifications included many types (e.g., print, tv, projection), modern practice primarily uses screen (for color screens) and all (default, applies to all devices).
| Media Type | Description |
|---|---|
all | Applies to all devices (default if omitted). |
screen | Applies to color computer screens, tablets, smartphones, etc. |
print | Applies to printed documents or print preview modes. |
speech | Applies to screen readers and other speech synthesizers. |
Example: Target screen devices only:
@media screen {
body { font-size: 16px; }
}
Note: The only keyword (e.g., only screen) is used to hide media queries from older browsers that don’t support CSS3 media queries. It has no effect on modern browsers.
Media Features
Media features are specific properties of the device or environment, such as width, height, or orientation. They are always wrapped in parentheses and paired with a value.
Common Media Features:
| Feature | Description |
|---|---|
width/min-width/max-width | Target viewport width (most used for responsive layouts). |
height/min-height/max-height | Target viewport height. |
orientation | portrait (height > width) or landscape (width > height). |
aspect-ratio | Aspect ratio of the viewport (e.g., 16/9 for widescreens). |
resolution | Pixel density (e.g., 2dppx for Retina displays). |
prefers-color-scheme | User’s system color preference (light or dark). |
prefers-reduced-motion | User’s preference for reduced animation (reduce or no-preference). |
Example: Apply styles when the viewport is at least 768px wide:
@media (min-width: 768px) {
.container { padding: 2rem; }
}
Logical Operators
Logical operators combine media types and features to create complex conditions.
and: Combine multiple conditions
All conditions must be true for the styles to apply.
/* Apply to screen devices AND viewport width ≥ 768px */
@media screen and (min-width: 768px) {
.nav { display: flex; }
}
not: Negate a condition
Applies styles when the condition is not met.
/* Apply to devices that are NOT print */
@media not print {
.header { background: #fff; }
}
, (comma): Logical OR
Applies styles if any condition is true (behaves like a logical “OR”).
/* Apply to screens ≥ 1200px OR print devices */
@media (min-width: 1200px), print {
.content { max-width: 800px; }
}
Breakpoints: Defining When Styles Change
Breakpoints are the specific viewport widths where your layout adjusts. They are the foundation of responsive design.
Mobile-First vs. Desktop-First Approaches
There are two primary strategies for defining breakpoints:
Mobile-First (Recommended)
Start with base styles for mobile devices, then use min-width to add styles for larger screens. This ensures a solid foundation for small devices and progressively enhances for larger ones.
Example:
/* Base styles (mobile-first: applies to all screens by default) */
body { margin: 0; padding: 1rem; }
/* Tablet: 768px and up */
@media (min-width: 768px) {
body { padding: 2rem; }
}
/* Desktop: 1200px and up */
@media (min-width: 1200px) {
body { padding: 3rem; }
}
Desktop-First
Start with base styles for desktop, then use max-width to override styles for smaller screens. This can lead to bloated CSS (more overrides) and is less mobile-friendly.
Example:
/* Base styles (desktop-first) */
body { padding: 3rem; }
/* Tablet: up to 1199px */
@media (max-width: 1199px) {
body { padding: 2rem; }
}
/* Mobile: up to 767px */
@media (max-width: 767px) {
body { padding: 1rem; }
}
Common Breakpoints and Best Practices
There’s no universal “right” set of breakpoints, but these are widely used as starting points:
| Device | min-width (Mobile-First) | max-width (Desktop-First) |
|---|---|---|
| Mobile | Base (no query) | ≤ 767px |
| Tablet | ≥ 768px | ≤ 1199px |
| Desktop | ≥ 1200px | ≤ 1439px |
| Large Desktop | ≥ 1440px | ≥ 1440px |
Best Practices:
- Use content-driven breakpoints (adjust when content looks “broken,” not just device sizes).
- Avoid too many breakpoints (3–5 is typical for most sites).
- Use relative units (e.g.,
rem,em) instead of fixed pixels for flexibility.
Advanced Media Features
Beyond width and height, media queries can target user preferences and device capabilities, enhancing accessibility and user experience.
User Preference Queries
These queries respect system-level user settings, making your site more inclusive.
prefers-color-scheme
Targets light/dark mode preferences:
/* Default light mode */
body { background: #fff; color: #333; }
/* Dark mode if user prefers it */
@media (prefers-color-scheme: dark) {
body { background: #1a1a1a; color: #fff; }
}
prefers-reduced-motion
Disables animations for users with vestibular disorders:
/* Default animation */
.button { transition: transform 0.3s ease; }
/* No animation if reduced motion is preferred */
@media (prefers-reduced-motion: reduce) {
.button { transition: none; }
}
Device Capability Queries
pointer
Targets devices with a precise pointer (e.g., mouse) vs. coarse (e.g., touch):
/* Touch devices: larger buttons */
@media (pointer: coarse) {
.button { padding: 1rem 2rem; }
}
/* Mouse devices: smaller buttons */
@media (pointer: fine) {
.button { padding: 0.5rem 1rem; }
}
hover
Check if the device supports hover (e.g., desktops vs. mobile):
@media (hover: hover) {
.link:hover { text-decoration: underline; }
}
Implementing Media Queries in Practice
Media queries can be applied in three key ways:
In CSS: @media Rule
The most common method—embed queries directly in your stylesheet:
/* Base styles */
.card { width: 100%; margin-bottom: 1rem; }
/* Tablet: 2 columns */
@media (min-width: 768px) {
.card { width: calc(50% - 1rem); float: left; margin-right: 1rem; }
.card:nth-child(2n) { margin-right: 0; }
}
In HTML: media Attribute
Apply stylesheets conditionally using the <link> tag’s media attribute:
<!-- Load mobile styles by default -->
<link rel="stylesheet" href="mobile.css">
<!-- Load tablet styles if viewport ≥ 768px -->
<link rel="stylesheet" href="tablet.css" media="(min-width:
768px)">
Note: Use sparingly—too many stylesheets can hurt performance.
In JavaScript: matchMedia()
Dynamically respond to media query changes with JavaScript:
const mediaQuery = window.matchMedia('(min-width: 768px)');
function handleScreenChange(e) {
if (e.matches) {
console.log('Viewport is ≥ 768px');
// Add desktop-specific behavior
} else {
console.log('Viewport is < 768px');
// Add mobile-specific behavior
}
}
// Run on initial load
handleScreenChange(mediaQuery);
// Listen for changes
mediaQuery.addEventListener('change', handleScreenChange);
Best Practices for Effective Media Queries
- Mobile-First by Default: Start with mobile styles and layer up—this ensures better performance on small devices.
- Keep It Simple: Avoid overly complex queries (e.g.,
(min-width: 768px) and (max-width: 1199px) and (orientation: landscape)). - Test Across Devices: Use browser dev tools (Chrome DevTools, Firefox Responsive Design Mode) and real devices.
- Combine Media Features: Group related styles into a single query instead of multiple separate ones.
/* Good: Combine features */ @media (min-width: 768px) and (orientation: landscape) { ... } - Avoid Redundancy: Reuse classes and mixins (e.g., with Sass) to reduce code duplication.
Common Pitfalls and How to Avoid Them
- Order of Queries: In mobile-first, list
min-widthqueries ascending (smallest to largest). For desktop-first, listmax-widthdescending (largest to smallest)./* Bad: Larger query first overrides smaller */ @media (min-width: 1200px) { ... } @media (min-width: 768px) { ... } /* This will never apply! */ /* Good: Ascending order */ @media (min-width: 768px) { ... } @media (min-width: 1200px) { ... } - Overlapping Breakpoints: Ensure queries don’t overlap unintentionally (e.g.,
min-width: 768pxandmax-width: 768px). - Forgetting
min-/max-:width: 768pxonly applies exactly at 768px—usemin-/max-for ranges.
Tools and Resources for Testing Media Queries
- Browser DevTools: Chrome, Firefox, and Safari have built-in responsive design tools.
- Sass Mixins: Simplify media queries with reusable mixins:
@mixin breakpoint($min-width) { @media (min-width: $min-width) { @content; } } // Usage: @include breakpoint(768px) { .container { padding: 2rem; } } - Online Generators: CSS Media Query Generator (CSS-Tricks).
- Testing Tools: BrowserStack, Sauce Labs.
Conclusion
Media queries are the cornerstone of responsive web design, enabling websites to adapt to the diverse array of devices and user preferences in today’s digital world. By mastering their syntax, leveraging advanced features, and following best practices, you can build flexible, accessible, and user-centric websites.
Remember: responsive design is about more than just “fitting on a screen”—it’s about delivering a seamless experience, regardless of how users choose to interact with your content.