Media Queries
Definition
Media queries are a CSS technique that enables developers to apply different style rules based on the characteristics of the device rendering the content. They form the technical foundation of responsive web design, allowing websites to adapt their layout and appearance to different screen sizes, resolutions, orientations, and other device capabilities.
Introduced in CSS3, media queries use the @media
rule to conditionally apply CSS when specific device conditions are met. This technique allows a single website to provide an optimal viewing experience across a wide range of devices, from desktop computers to smartphones, without requiring separate websites for different devices.
Syntax and Structure
The basic syntax of a media query consists of:
- The
@media
rule - An optional media type (e.g.,
screen
,print
) - One or more expressions that check for specific conditions
- The CSS rules to apply when conditions are met
@media [media-type] and ([feature]: [value]) {
/* CSS rules to apply when conditions are met */
}
Basic Example
/* Base styles for all devices */
body {
font-size: 16px;
padding: 10px;
}
/* Styles for screens at least 768px wide */
@media screen and (min-width: 768px) {
body {
font-size: 18px;
padding: 20px;
}
}
/* Styles for screens at least 1200px wide */
@media screen and (min-width: 1200px) {
body {
font-size: 20px;
padding: 30px;
max-width: 1140px;
margin: 0 auto;
}
}
Media Types
Media types specify the general category of device the styles should apply to:
all
: Default; matches all devicesscreen
: Computers, tablets, phones, and similar screensprint
: Print preview mode and printed pagesspeech
: Screen readers and other audio browsers
Example with Media Type
/* Styles for printed documents */
@media print {
body {
font-size: 12pt;
color: black;
background: white;
}
nav, .ads, .social-buttons {
display: none; /* Hide navigation and other elements when printing */
}
a::after {
content: " (" attr(href) ")"; /* Show URLs after links when printing */
}
}
Media Features
Media features describe specific characteristics of the user agent, output device, or environment:
Viewport Dimensions
width
,min-width
,max-width
: Viewport widthheight
,min-height
,max-height
: Viewport height
/* Apply when viewport is between 768px and 1200px wide */
@media (min-width: 768px) and (max-width: 1199px) {
.container {
width: 750px;
}
}
Display Quality
resolution
: Pixel density (dpi/dpcm/dppx)orientation
: Portrait or landscapeaspect-ratio
: Width-to-height ratio
/* High-resolution (retina) displays */
@media (min-resolution: 2dppx) {
.logo {
background-image: url('logo@2x.png');
background-size: 200px 50px;
}
}
/* Landscape orientation */
@media (orientation: landscape) {
.gallery {
display: flex;
flex-direction: row;
}
}
Device Capabilities
hover
: Ability to hover over elementspointer
: Presence and accuracy of pointing devicecolor
: Number of bits per color componentcolor-gamut
: Approximate range of colors
/* Styles for touch devices without hover capability */
@media (hover: none) and (pointer: coarse) {
button {
min-height: 44px; /* Larger touch targets */
min-width: 44px;
}
}
/* Styles for devices that support wide color gamuts */
@media (color-gamut: p3) {
.vibrant-element {
color: color(display-p3 1 0 0); /* Pure red in Display P3 */
}
}
User Preferences
prefers-reduced-motion
: Motion sensitivity preferenceprefers-color-scheme
: Light or dark theme preferenceprefers-contrast
: Contrast preferenceprefers-reduced-data
: Data usage preference
/* Respect user preference for reduced motion */
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
/* Dark mode support */
@media (prefers-color-scheme: dark) {
:root {
--text-color: #f0f0f0;
--background-color: #121212;
}
}
Logical Operators
Media queries can use logical operators to create more complex conditions:
and
: Both conditions must be truenot
: Negates the query,
(comma): Acts as an "or" operator; any condition can be trueonly
: Used to hide media queries from older browsers
/* AND operator: both conditions must be met */
@media (min-width: 768px) and (orientation: landscape) {
/* Apply when viewport is at least 768px wide AND in landscape orientation */
}
/* OR operator (comma): either condition can be met */
@media (max-width: 767px), (orientation: portrait) {
/* Apply when viewport is narrower than 768px OR in portrait orientation */
}
/* NOT operator: negates the entire query */
@media not all and (min-width: 1200px) {
/* Apply when NOT on a screen at least 1200px wide */
}
Common Breakpoints
While breakpoints should be based on content rather than specific devices, these common breakpoints serve as useful starting points:
/* Small devices (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) { ... }
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) { ... }
/* Extra extra large devices (1400px and up) */
@media (min-width: 1400px) { ... }
Mobile-First vs. Desktop-First Approach
Mobile-First (using min-width
):
/* Base styles for mobile */
body {
font-size: 16px;
}
/* Tablet styles */
@media (min-width: 768px) {
body {
font-size: 18px;
}
}
/* Desktop styles */
@media (min-width: 1200px) {
body {
font-size: 20px;
}
}
Desktop-First (using max-width
):
/* Base styles for desktop */
body {
font-size: 20px;
}
/* Tablet styles */
@media (max-width: 1199px) {
body {
font-size: 18px;
}
}
/* Mobile styles */
@media (max-width: 767px) {
body {
font-size: 16px;
}
}
Implementing Media Queries
In CSS Files
Media queries can be placed directly in CSS files:
/* styles.css */
.container {
width: 100%;
padding: 15px;
}
@media (min-width: 768px) {
.container {
width: 750px;
margin: 0 auto;
}
}
In HTML Link Element
Media queries can also be included in the media
attribute of <link>
elements:
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="mobile.css" media="(max-width: 767px)">
<link rel="stylesheet" href="tablet.css" media="(min-width: 768px) and (max-width: 1199px)">
<link rel="stylesheet" href="desktop.css" media="(min-width: 1200px)">
Using @import
Media queries can be used with CSS @import
rules (though this method can impact performance):
/* main.css */
@import url('base.css');
@import url('mobile.css') (max-width: 767px);
@import url('tablet.css') (min-width: 768px) and (max-width: 1199px);
@import url('desktop.css') (min-width: 1200px);
Within JavaScript
Media queries can be tested with JavaScript using window.matchMedia()
:
const mediaQuery = window.matchMedia('(min-width: 768px)');
function handleScreenChange(e) {
if (e.matches) {
console.log('Viewport is at least 768px wide');
// Execute desktop-specific JavaScript
} else {
console.log('Viewport is narrower than 768px');
// Execute mobile-specific JavaScript
}
}
// Initial check
handleScreenChange(mediaQuery);
// Listen for changes
mediaQuery.addEventListener('change', handleScreenChange);
Common Patterns and Examples
Responsive Navigation
/* Mobile: hamburger menu */
.nav-links {
display: none;
}
.hamburger {
display: block;
}
.nav-links.active {
display: flex;
flex-direction: column;
}
/* Desktop: horizontal navigation */
@media (min-width: 768px) {
.nav-links {
display: flex;
flex-direction: row;
}
.hamburger {
display: none;
}
}
Responsive Grid Layout
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
@media (min-width: 576px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 992px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (min-width: 1200px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
Responsive Typography
:root {
/* Base font size (16px) */
font-size: 100%;
}
h1 {
font-size: 2rem; /* 32px */
}
@media (min-width: 768px) {
h1 {
font-size: 2.5rem; /* 40px */
}
}
@media (min-width: 1200px) {
h1 {
font-size: 3rem; /* 48px */
}
}
/* Fluid typography using calc() */
h2 {
font-size: calc(1.25rem + 1vw);
}