CSS Media Queries
Media queries apply CSS based on device characteristics like screen size, orientation, and resolution.
Basic Syntax
@media (condition) {
/* CSS rules */
}
Screen Size Breakpoints
Common Breakpoints
/* Mobile: 0 - 576px */
/* Tablet: 577px - 768px */
/* Desktop: 769px - 992px */
/* Large: 993px - 1200px */
/* Extra Large: 1201px+ */
/* Mobile first (recommended) */
.container {
padding: 1rem;
}
@media (min-width: 576px) {
.container {
padding: 2rem;
}
}
@media (min-width: 768px) {
.container {
max-width: 720px;
margin: 0 auto;
}
}
@media (min-width: 992px) {
.container {
max-width: 960px;
}
}
@media (min-width: 1200px) {
.container {
max-width: 1140px;
}
}
Max-Width Approach
/* Desktop first */
.container {
max-width: 1140px;
margin: 0 auto;
}
@media (max-width: 1200px) {
.container {
max-width: 960px;
}
}
@media (max-width: 768px) {
.container {
padding: 1rem;
}
}
Media Features
Width and Height
/* Min width */
@media (min-width: 768px) { }
/* Max width */
@media (max-width: 768px) { }
/* Exact width */
@media (width: 1024px) { }
/* Height */
@media (min-height: 600px) { }
Orientation
/* Portrait */
@media (orientation: portrait) { }
/* Landscape */
@media (orientation: landscape) { }
Resolution
/* High DPI (Retina) */
@media (min-resolution: 2dppx) { }
/* Standard resolution */
@media (max-resolution: 1dppx) { }
Hover Capability
/* Devices that support hover */
@media (hover: hover) {
.button:hover {
background-color: #2980b9;
}
}
/* Touch devices */
@media (hover: none) {
.button:active {
background-color: #2980b9;
}
}
Pointer Accuracy
/* Fine pointer (mouse) */
@media (pointer: fine) { }
/* Coarse pointer (touch) */
@media (pointer: coarse) {
/* Make buttons larger for touch */
button {
padding: 15px 30px;
}
}
Multiple Conditions
/* AND */
@media (min-width: 768px) and (orientation: landscape) { }
/* OR */
@media (max-width: 576px), (orientation: portrait) { }
/* NOT */
@media not print { }
Complete Example: Responsive Layout
/* Mobile first */
.page {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
gap: 1rem;
}
.page-header,
.page-footer {
padding: 1rem;
background-color: #333;
color: white;
}
.page-content {
padding: 1rem;
}
/* Tablet */
@media (min-width: 768px) {
.page {
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
}
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-content { grid-area: content; }
.page-footer { grid-area: footer; }
}
/* Desktop */
@media (min-width: 992px) {
.page {
grid-template-columns: 250px 1fr 200px;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
}
}
Complete Example: Responsive Typography
/* Mobile first */
html {
font-size: 14px;
}
h1 {
font-size: 1.75rem;
}
h2 {
font-size: 1.5rem;
}
p {
font-size: 1rem;
line-height: 1.6;
}
/* Tablet */
@media (min-width: 768px) {
html {
font-size: 15px;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.75rem;
}
}
/* Desktop */
@media (min-width: 992px) {
html {
font-size: 16px;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
}
}
Complete Example: Responsive Navigation
/* Mobile: Hamburger menu */
.nav {
display: flex;
flex-direction: column;
padding: 1rem;
}
.nav-toggle {
display: block;
margin-left: auto;
}
.nav-menu {
display: none;
flex-direction: column;
gap: 1rem;
margin-top: 1rem;
}
.nav-menu.active {
display: flex;
}
/* Tablet/Desktop: Horizontal nav */
@media (min-width: 768px) {
.nav {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.nav-toggle {
display: none;
}
.nav-menu {
display: flex;
flex-direction: row;
margin-top: 0;
}
}
Complete Example: Responsive Cards
/* Mobile: Single column */
.card-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
padding: 1rem;
}
.card {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 10px;
}
/* Tablet: 2 columns */
@media (min-width: 576px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop: 3 columns */
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
padding: 2rem;
}
}
/* Large desktop: 4 columns */
@media (min-width: 992px) {
.card-grid {
grid-template-columns: repeat(4, 1fr);
}
}
Complete Example: Responsive Images
/* Mobile first */
img {
max-width: 100%;
height: auto;
}
.hero-image {
width: 100%;
height: 200px;
object-fit: cover;
}
/* Tablet */
@media (min-width: 768px) {
.hero-image {
height: 400px;
}
}
/* Desktop */
@media (min-width: 992px) {
.hero-image {
height: 500px;
}
}
Accessibility
prefers-reduced-motion
/* Respect user's motion preferences */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
prefers-color-scheme
/* Dark mode */
@media (prefers-color-scheme: dark) {
body {
background-color: #333;
color: white;
}
}
/* Light mode */
@media (prefers-color-scheme: light) {
body {
background-color: white;
color: #333;
}
}
Mobile-First vs Desktop-First
Mobile-First (Recommended)
/* Base styles for mobile */
.container {
padding: 1rem;
}
/* Add styles for larger screens */
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
Benefits:
- Better performance on mobile
- Cleaner, more maintainable code
- Progressive enhancement
Desktop-First
/* Base styles for desktop */
.container {
padding: 2rem;
}
/* Override for smaller screens */
@media (max-width: 768px) {
.container {
padding: 1rem;
}
}
Best Practices
- Use mobile-first — Better performance
- Define breakpoints based on content — Not devices
- Keep breakpoints minimal — 3-4 is usually enough
- Test on real devices — Not just browser resize
- Use relative units — rem, %, vw
Common Mistakes
- Desktop-first approach — Less maintainable
- Too many breakpoints — Over-complicates CSS
- Using device-specific queries — Breaks on new devices
- Not testing on real devices — Browser resize isn’t accurate
- Forgetting landscape orientation — Tablets are used both ways