What are Media Queries?
Media queries are the backbone of responsive web design, allowing CSS to apply different styles based on the characteristics of the device or browser viewport. Think of media queries as filters that examine the current state of the browsing environment and apply CSS rules only when specific conditions are met.
Just as a thermostat in your home triggers the heating system when the temperature drops below a certain threshold, media queries trigger specific CSS rules when the viewport meets particular conditions (like being narrower than 768 pixels).
Before media queries, creating websites that adapted to different screen sizes required separate versions of the site or complex JavaScript solutions. Media queries revolutionized web development by providing a pure CSS approach to responsive design.
Anatomy of a Media Query
Let's break down the structure of a media query to understand its components:
@media media-type and (media-feature-rule) {
/* CSS rules to be applied when media query matches */
selector {
property: value;
}
}
The key components are:
- @media - The keyword that begins every media query
- media-type - The type of media you're targeting (screen, print, speech, all)
- logical operators - Keywords like 'and', 'not', or 'only' that combine conditions
- media-feature-rule - Conditions that test for specific device characteristics
- CSS rules - The styles to apply when conditions are met
Real-world analogy: Think of media queries like a bouncer at a club. The media type is like checking if someone is on the guest list (are they using a screen, printer, etc.). Media features are like additional entry requirements (are they over 21, dressed appropriately, etc.). Only when all conditions are met does the person (or in our case, the CSS rules) get to enter.
Media Types
Media types define the broad category of device. While there are several media types in the specification, these are the most commonly used:
- all - Applies to all devices (default if not specified)
- screen - Applies to computer screens, tablets, smartphones, etc.
- print - Applies when the content is being printed or viewed in print preview
- speech - Applies to screen readers and other audio-based browsers
Print Media Example
/* Normal screen styles */
body {
background-color: #f5f5f5;
color: #333;
}
/* Print-specific styles */
@media print {
body {
background-color: white;
color: black;
font-size: 12pt;
}
/* Hide navigation and interactive elements when printing */
nav, button, .ads, .comments {
display: none;
}
/* Ensure links show their URLs */
a[href]:after {
content: " (" attr(href) ")";
}
}
Practical application: Print media queries are incredibly useful for creating printer-friendly versions of your content. They allow you to strip away navigation, adjust typography for paper, and even add content (like URLs) that makes the printed page more useful without cluttering the screen version.
Media Features
Media features are the conditions we test for within media queries. They allow us to target specific characteristics of the user's device or browser.
Width-based Media Features
- width - Viewport width
- min-width - Minimum viewport width
- max-width - Maximum viewport width
/* Base mobile styles */
.container {
padding: 10px;
}
/* Tablets and larger */
@media screen and (min-width: 768px) {
.container {
padding: 20px;
}
}
/* Desktops and larger */
@media screen and (min-width: 1024px) {
.container {
padding: 30px;
max-width: 1200px;
margin: 0 auto;
}
}
Note: min-width and max-width are more commonly used than the exact width, as they allow for more flexible designs that work across a range of screen sizes.
Height-based Media Features
- height - Viewport height
- min-height - Minimum viewport height
- max-height - Maximum viewport height
/* Adjust hero section for shorter screens */
@media screen and (max-height: 600px) {
.hero {
min-height: auto;
padding: 20px 0;
}
.hero h1 {
font-size: 1.5rem;
}
}
Real-world use case: Height-based queries are particularly useful for adjusting full-height elements on shorter screens, such as when a mobile device is in landscape orientation or on netbooks with limited vertical space.
Device Pixel Ratio Media Features
- device-pixel-ratio - Ratio of device pixels to CSS pixels
- min-device-pixel-ratio - Minimum ratio
- max-device-pixel-ratio - Maximum ratio
- resolution - Pixel density in dpi or dpcm
/* Standard resolution */
.logo {
background-image: url('logo.png');
}
/* High resolution screens (like Retina displays) */
@media (-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
.logo {
background-image: url('logo@2x.png');
}
}
Real-world application: Device pixel ratio queries allow you to serve higher-resolution images to devices with high-density displays (like Apple's Retina displays), while still serving appropriately sized images to standard displays. This helps maintain visual quality without unnecessarily increasing load times for all users.
Orientation Media Features
- orientation: portrait - Height is greater than or equal to width
- orientation: landscape - Width is greater than height
/* Default layout */
.gallery {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
}
/* Landscape orientation - more horizontal space */
@media screen and (orientation: landscape) {
.gallery {
grid-template-columns: repeat(3, 1fr);
}
}
Real-world use case: Orientation queries are excellent for creating interfaces that adapt to how a user is holding their device. For example, a photo gallery might display in a single column in portrait mode but expand to multiple columns in landscape mode to take advantage of the wider screen.
Other Useful Media Features
- aspect-ratio - Ratio of width to height of the viewport
- color - Number of bits per color component
- display-mode - How the web application is displayed (browser, standalone, fullscreen)
- prefers-reduced-motion - User has requested minimal animations
- prefers-color-scheme - User prefers light or dark color themes
- hover - Primary input mechanism can hover
- pointer - Primary input mechanism is coarse (touch) or fine (mouse)
These additional features allow for even more tailored experiences based on user preferences and device capabilities.
Logical Operators in Media Queries
Media queries support logical operators that allow you to create more complex conditions:
The 'and' Operator
The 'and' operator combines multiple conditions that must all be true for the query to apply.
/* Apply only when both conditions are met */
@media screen and (min-width: 768px) and (max-width: 1023px) {
/* Tablet-specific styles */
body {
font-size: 16px;
}
}
Real-world use case: The 'and' operator is perfect for targeting specific ranges, like creating styles exclusively for tablets by targeting screen widths between 768px and 1023px.
The 'not' Operator
The 'not' operator negates the query, applying styles when the conditions are NOT met.
/* Apply to everything except screens */
@media not screen {
/* Styles for print, speech, etc. */
body {
background: none;
}
}
Note: The 'not' operator applies to the entire query, not just a part of it.
The 'only' Operator
The 'only' operator is primarily used to hide media queries from older browsers that don't support them.
@media only screen and (min-width: 768px) {
/* These styles will be ignored by very old browsers */
.container {
width: 750px;
}
}
Note: Modern browsers no longer need the 'only' operator, but it's sometimes still included for backwards compatibility.
Using Commas for 'OR' Logic
Commas function like the 'OR' operator, allowing you to apply styles when any of the comma-separated conditions are true.
/* Apply when either condition is met */
@media screen and (max-width: 767px), print {
/* Styles for both mobile devices and print */
.sidebar {
display: none;
}
}
Real-world use case: This approach is useful when you want to apply the same styles in multiple contexts - for example, hiding a sidebar both on small screens and when printing.
Mobile-First vs. Desktop-First with Media Queries
Desktop-First Approach (Traditional)
In a desktop-first approach, you design for the desktop experience first and then use media queries with max-width to adapt the design for smaller screens.
/* Desktop styles (default) */
.container {
width: 1140px;
margin: 0 auto;
}
/* Tablet styles */
@media screen and (max-width: 1023px) {
.container {
width: 90%;
}
}
/* Mobile styles */
@media screen and (max-width: 767px) {
.container {
width: 100%;
padding: 0 15px;
}
}
Analogy: Desktop-first is like starting with a large, fully-furnished house and then figuring out what furniture to remove to fit into a smaller apartment. You begin with everything and then start taking away.
Mobile-First Approach (Recommended)
In a mobile-first approach, you design for the mobile experience first and then use media queries with min-width to enhance the design for larger screens.
/* Mobile styles (default) */
.container {
width: 100%;
padding: 0 15px;
}
/* Tablet styles */
@media screen and (min-width: 768px) {
.container {
width: 90%;
margin: 0 auto;
}
}
/* Desktop styles */
@media screen and (min-width: 1024px) {
.container {
width: 1140px;
}
}
Analogy: Mobile-first is like starting with a backpack containing only essential items for a hike, and then adding more items as you get a bigger backpack. You begin with the essentials and progressively enhance.
Why Mobile-First is Often Better
- Progressive enhancement - Start with a baseline experience and enhance it for larger screens and more capable devices
- Performance optimization - Mobile devices often have less processing power and potentially slower connections
- Content prioritization - Forces you to focus on what's most important when space is limited
- Future-proofing - As mobile usage continues to grow, designing for mobile first aligns with user trends
- Simpler CSS - Generally results in cleaner, more maintainable CSS
Real-world impact: Many major websites and frameworks (like Bootstrap) have shifted to a mobile-first approach over the years, recognizing that starting with the constraints of mobile creates more focused, efficient designs that scale up well to larger screens.
Common Breakpoints for Media Queries
While you should ideally set breakpoints based on your content rather than specific devices, these standard breakpoints provide a good starting point:
| Device Category | Breakpoint Range | Common Values |
|---|---|---|
| Small mobile devices | 320px - 575px | 320px, 480px |
| Large mobile devices | 576px - 767px | 576px |
| Tablets | 768px - 991px | 768px |
| Laptops/small desktops | 992px - 1199px | 992px |
| Large desktops | 1200px and above | 1200px, 1400px |
Bootstrap 5 Breakpoints
For reference, these are the breakpoints used by the popular Bootstrap framework:
// Small devices (landscape phones, 576px and up)
@media (min-width: 576px) { ... }
// Medium devices (tablets, 768px and up)
@media (min-width: 768px) { ... }
// Large devices (desktops, 992px and up)
@media (min-width: 992px) { ... }
// X-Large devices (large desktops, 1200px and up)
@media (min-width: 1200px) { ... }
// XX-Large devices (larger desktops, 1400px and up)
@media (min-width: 1400px) { ... }
Important consideration: Rather than targeting specific devices, focus on where your content and layout naturally need to adjust. This approach, known as "content-first" breakpoints, results in designs that work well across a wider range of devices.
Practical Examples of Media Queries
Responsive Navigation
One of the most common uses for media queries is creating a responsive navigation menu:
/* Mobile-first navigation (hamburger menu) */
.nav-toggle {
display: block; /* Show hamburger icon */
}
.nav-menu {
display: none; /* Hide menu by default */
}
.nav-menu.active {
display: block; /* Show when toggled */
position: absolute;
top: 60px;
left: 0;
width: 100%;
background: #fff;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.nav-menu li {
display: block;
border-bottom: 1px solid #eee;
}
/* Desktop navigation */
@media screen and (min-width: 768px) {
.nav-toggle {
display: none; /* Hide hamburger icon */
}
.nav-menu {
display: flex; /* Always show menu */
position: static;
box-shadow: none;
}
.nav-menu li {
display: inline-block;
border-bottom: none;
margin-left: 20px;
}
}
Real-world implementation: This pattern is used on countless websites to transform a horizontal navigation on desktop into a space-saving hamburger menu on mobile devices.
Responsive Grid Layout
Creating a grid layout that adjusts columns based on screen size:
/* Mobile: Single column */
.grid-container {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
/* Tablet: Two columns */
@media screen and (min-width: 768px) {
.grid-container {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop: Four columns */
@media screen and (min-width: 1024px) {
.grid-container {
grid-template-columns: repeat(4, 1fr);
}
}
Real-world application: This approach is ideal for product listings, image galleries, blog posts, and any content that benefits from a grid layout.
Font Size Adjustments
Adjusting typography for different screen sizes:
/* Base typography (mobile) */
body {
font-size: 16px;
}
h1 {
font-size: 1.75rem;
line-height: 1.2;
}
h2 {
font-size: 1.5rem;
line-height: 1.2;
}
/* Tablet typography */
@media screen and (min-width: 768px) {
body {
font-size: 17px;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.75rem;
}
}
/* Desktop typography */
@media screen and (min-width: 1024px) {
body {
font-size: 18px;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
}
}
Design principle: Typography should scale proportionally with screen size, but not in a strictly linear fashion. Reading comfort requires different sizing adjustments at different screen sizes.
Responsive Images
Using media queries with the picture element for art direction:
<picture>
<source media="(min-width: 1024px)" srcset="image-large.jpg">
<source media="(min-width: 768px)" srcset="image-medium.jpg">
<img src="image-small.jpg" alt="Responsive Image">
</picture>
Use case: This approach allows you to not only serve differently sized images but also differently cropped or composed images based on screen size. For example, a landscape-oriented hero image on desktop might be replaced with a portrait-oriented version on mobile.
Advanced Media Query Techniques
Nested Media Queries in Sass/SCSS
CSS preprocessors like Sass allow you to nest media queries within selectors, making your code more organized:
// SCSS
.card {
padding: 15px;
@media screen and (min-width: 768px) {
padding: 20px;
}
.card-title {
font-size: 1.2rem;
@media screen and (min-width: 768px) {
font-size: 1.5rem;
}
}
}
This compiles to:
/* Compiled CSS */
.card {
padding: 15px;
}
@media screen and (min-width: 768px) {
.card {
padding: 20px;
}
}
.card .card-title {
font-size: 1.2rem;
}
@media screen and (min-width: 768px) {
.card .card-title {
font-size: 1.5rem;
}
}
Development benefit: Nesting media queries keeps related styles together in your source code, making maintenance easier and helping developers understand the relationship between base styles and their responsive variations.
Feature Queries with @supports
Combine media queries with feature queries for progressive enhancement:
/* Basic styling for all browsers */
.container {
display: block;
}
/* Enhanced with Flexbox for browsers that support it */
@supports (display: flex) {
.container {
display: flex;
flex-wrap: wrap;
}
/* Make flexbox responsive */
@media screen and (max-width: 767px) {
.container {
flex-direction: column;
}
}
}
Progressive enhancement: This approach allows you to provide a baseline experience for all browsers while enhancing the experience for those that support modern features. The media query inside the @supports block creates responsive behavior only when the feature is supported.
Container Queries (Emerging Standard)
Container queries are an evolving feature that allows components to respond to their parent container's size rather than the viewport:
/* Define a containment context */
.card-container {
container-type: inline-size;
}
/* Base card styles */
.card {
padding: 15px;
}
/* When the container is at least 400px wide */
@container (min-width: 400px) {
.card {
padding: 20px;
display: flex;
}
}
The future of responsive design: Container queries represent a shift from viewport-centric to component-centric responsive design. They allow reusable components to adapt based on their immediate context rather than the overall page size, which is especially valuable for design systems and component libraries.
Preference Queries
Media queries that respond to user preferences:
/* Default light theme */
:root {
--background-color: #fff;
--text-color: #333;
}
/* Dark theme for users who prefer it */
@media (prefers-color-scheme: dark) {
:root {
--background-color: #222;
--text-color: #f0f0f0;
}
}
/* Reduce animations for users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
Accessibility benefit: Preference queries allow your design to respect user needs and preferences at the operating system level, which is particularly important for accessibility and user experience. For example, users with vestibular disorders often enable reduced motion settings to prevent discomfort from animations.
Common Media Query Mistakes and Best Practices
Common Mistakes
- Using too many breakpoints - This creates maintenance headaches and often results in brittle designs
- Designing for specific devices - Device dimensions constantly change; focus on content needs instead
- Forgetting to include the viewport meta tag - Without this, mobile browsers won't respect your media queries
- Inconsistent units - Mixing pixels, ems, and rems can lead to unexpected behavior
- Overriding too many styles - Excessive overrides indicate your base styles might not be well-structured
- Not testing actual devices - Emulators and responsive design mode aren't perfect substitutes
Best Practices
- Start mobile-first - Begin with styles for the smallest screens and enhance for larger ones
- Use relative units - Prefer percentages, ems, and rems over fixed pixels
- Group media queries by component - Keeps related styles together for easier maintenance
- Test on actual devices - Use real hardware when possible to catch issues emulators might miss
- Use developer tools - Browser dev tools include responsive design modes for quick testing
- Focus on content breakpoints - Let your content determine when layout should change
- Document your approach - Comment your breakpoint strategy for other developers
Performance Considerations
Media queries can impact performance if not handled carefully:
- Avoid unnecessary downloads - Use media queries in link tags to conditionally load stylesheets
- Minimize repaints and reflows - Change properties that cause minimal layout recalculation
- Consider using JavaScript judiciously - For complex responsive behaviors, sometimes JS is more efficient
<!-- Conditionally load CSS based on viewport size -->
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="tablet.css" media="screen and (min-width: 768px)">
<link rel="stylesheet" href="desktop.css" media="screen and (min-width: 1024px)">
Performance benefit: With this approach, browsers will only download the CSS files relevant to the current viewport size, reducing initial load time, particularly for mobile users.
Practical Workshop: Building a Responsive Component
Let's apply what we've learned by building a responsive card component that adapts across different screen sizes:
HTML Structure
<div class="product-card">
<div class="product-image">
<img src="product.jpg" alt="Product Name">
</div>
<div class="product-info">
<h3 class="product-title">Product Name</h3>
<p class="product-description">This is a short description of the product and its features.</p>
<div class="product-meta">
<span class="product-price">$29.99</span>
<button class="product-button">Add to Cart</button>
</div>
</div>
</div>
CSS with Media Queries
/* Base styles (mobile-first) */
.product-card {
border: 1px solid #eee;
border-radius: 8px;
overflow: hidden;
background: white;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.product-image img {
width: 100%;
height: auto;
display: block;
}
.product-info {
padding: 15px;
}
.product-title {
margin-top: 0;
margin-bottom: 10px;
font-size: 1.2rem;
}
.product-description {
margin-bottom: 15px;
font-size: 0.9rem;
color: #666;
}
.product-meta {
display: flex;
justify-content: space-between;
align-items: center;
}
.product-price {
font-weight: bold;
font-size: 1.1rem;
}
.product-button {
background: #0066cc;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
}
/* Tablet styles */
@media screen and (min-width: 768px) {
.product-card {
display: flex;
max-height: 200px;
}
.product-image {
flex: 0 0 200px;
}
.product-image img {
height: 100%;
object-fit: cover;
}
.product-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.product-title {
font-size: 1.3rem;
}
}
/* Desktop styles */
@media screen and (min-width: 1024px) {
.product-card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.product-card:hover {
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.product-button {
opacity: 0.9;
transition: opacity 0.3s ease, background-color 0.3s ease;
}
.product-button:hover {
opacity: 1;
background-color: #0055aa;
}
}
/* Large desktop styles */
@media screen and (min-width: 1400px) {
.product-info {
padding: 20px;
}
.product-title {
font-size: 1.5rem;
}
.product-description {
font-size: 1rem;
}
}
This responsive component demonstrates:
- Mobile-first approach starting with a vertical card layout
- Transition to a horizontal layout for tablets and larger screens
- Progressive enhancement with hover effects only on desktop
- Subtle refinements to spacing and typography as screen size increases
- Use of flexbox for layout changes instead of completely rewriting styles
Real-world application: This card pattern is commonly used for product listings in e-commerce, article previews in blogs, and content cards in dashboards and apps.
Testing Media Queries
Browser Developer Tools
Most modern browsers include responsive design mode in their developer tools:
- Chrome/Edge: Open Dev Tools (F12) → Click the device icon or press Ctrl+Shift+M
- Firefox: Open Dev Tools (F12) → Click the responsive design mode icon or press Ctrl+Shift+M
- Safari: Open Dev Tools → Click on the Responsive Design Mode icon
Browser Extensions
Extensions can enhance your media query testing workflow:
- Responsive Viewer - Shows your site in multiple viewports simultaneously
- Window Resizer - Quickly resize your browser window to common dimensions
- What's My Browser Size - Displays the current viewport dimensions
Online Testing Tools
- Responsively App - Desktop application for responsive development
- BrowserStack - Test on real mobile devices in the cloud
- Am I Responsive - Quick visualization of your site on multiple devices
Testing Checklist
When testing your media queries, check the following:
- Does the layout adapt smoothly across different screen sizes?
- Is the text readable at all viewport widths?
- Are touch targets big enough on small screens?
- Does the site work in both portrait and landscape orientations?
- Is the navigation usable across all breakpoints?
- Are images loading appropriately for each screen size?
- Does the site perform well on low-power devices?
Conclusion: The Power of Media Queries
Media queries are the foundation that makes responsive web design possible. They allow us to create websites that provide optimal experiences across an ever-expanding range of devices and screen sizes.
Remember that effective responsive design isn't just about making things fit on different screens—it's about delivering the right experience for each context. Media queries give us the tool to create these contextual experiences, adapting not just layout but typography, interaction, and even content to meet users where they are.
As web technology continues to evolve, the role of media queries is expanding beyond just screen sizes to include user preferences, device capabilities, and environmental conditions. By mastering media queries, you're equipping yourself with a fundamental skill that will remain relevant even as the specifics of web design continue to evolve.
In our next session, we'll explore how to combine media queries with modern layout techniques like Flexbox and CSS Grid to create even more powerful responsive designs with less code.
Daily Assignment: Media Query Mastery
Apply today's concepts by creating a responsive webpage that demonstrates effective use of media queries:
- Create a webpage with a header, main content area with cards, sidebar, and footer
- Implement a mobile-first approach with at least 3 breakpoints
- The layout should stack vertically on mobile, with the sidebar below the main content
- On tablets, implement a 2-column card layout and keep the sidebar below
- On desktop, create a 3-column layout for cards and move the sidebar to the right
- Include at least one print media query that optimizes the page for printing
- Implement at least one preference query (dark mode or reduced motion)
Requirements:
- Use semantic HTML elements
- Include proper viewport meta tag
- Comment your media queries to explain your approach
- Test on at least three different viewport sizes
- Use relative units throughout your CSS
Create this in a file called 04week/media_queries_assignment.html and submit it to the course repository by the end of day.