|$ curl https://forge-ai.dev/api/markdown?path=docs/css/media-queries
$cat docs/css-media-queries.md
updated Yesterday·10 min read·published

CSS Media Queries

CSSMedia QueriesResponsiveBeginner
Introduction

CSS media queries are the cornerstone of responsive web design. They allow you to apply styles conditionally based on the characteristics of the device or viewport — most commonly its width, height, orientation, or user preferences. Media queries enable a single codebase to adapt seamlessly across phones, tablets, laptops, and large screens.

The syntax combines a media type (screen, print, all) with optional media features in parentheses, creating boolean conditions that match when all criteria are satisfied.

media-queries-intro.css
CSS
1@media screen and (max-width: 768px) {
2 .container {
3 flex-direction: column;
4 padding: 16px;
5 }
6}
7
8/* Multiple conditions */
9@media (min-width: 768px) and (max-width: 1024px) {
10 .sidebar {
11 width: 200px;
12 }
13}
The @media Rule

The @media at-rule is the core of responsive CSS. It can be used at the top level of a stylesheet or nested inside other conditional rules. It evaluates a media query list and applies the enclosed styles if the query matches.

at-media.css
CSS
1.box {
2 width: 100%;
3 max-width: 1200px;
4 margin: 0 auto;
5}
6
7/* Apply styles when viewport is 768px or narrower */
8@media (max-width: 768px) {
9 .box {
10 padding: 12px;
11 }
12}
13
14/* Media queries can also be used in the HTML link tag */
15/*
16<link rel="stylesheet" href="mobile.css" media="screen and (max-width: 768px)">
17<link rel="stylesheet" href="print.css" media="print">
18*/
Media Types

Media types specify the general category of device a stylesheet applies to. The most commonly used types are screen, print, and all.

media-types.css
CSS
1.header {
2 background: linear-gradient(135deg, #0D0D0D, #1A1A2E);
3}
4
5/* Print styles — hide non-essential elements */
6@media print {
7 .header {
8 background: none;
9 color: black;
10 }
11 .nav, .sidebar, .ad-banner {
12 display: none;
13 }
14 body {
15 font-size: 12pt;
16 }
17}
18
19/* Media types */
20@media screen {
21 /* For all screen devices */
22}
23
24@media print {
25 /* For printed pages and print preview */
26}
27
28@media all {
29 /* For all devices (default) */
30}
31
32/* Speech (screen readers) */
33@media speech {
34 /* For aural/speech synthesizers */
35}
Media Features

Media features describe specific characteristics of the user's device or browsing environment. They are the conditional part of the media query that determines whether the styles apply.

Width & Height

media-width-height.css
CSS
1.layout {
2 display: grid;
3 grid-template-columns: 1fr 1fr 1fr;
4 gap: 24px;
5}
6
7/* max-width — target sizes BELOW the threshold */
8@media (max-width: 1024px) {
9 .layout { grid-template-columns: 1fr 1fr; }
10}
11
12/* min-width — target sizes ABOVE the threshold */
13@media (min-width: 1200px) {
14 .layout { grid-template-columns: 1fr 1fr 1fr 1fr; }
15}
16
17/* Combining width and height */
18@media (min-width: 768px) and (max-width: 1024px) {
19 .layout { gap: 16px; }
20}
21
22/* width and height are the most common features */
23/*
24 width — viewport width (min-/max- prefixes)
25 height — viewport height
26 device-width — deprecated, use width instead
27 aspect-ratio — width/height ratio
28*/

orientation

media-orientation.css
CSS
1.panel {
2 display: flex;
3}
4
5@media (orientation: portrait) {
6 .panel {
7 flex-direction: column;
8 }
9}
10
11@media (orientation: landscape) {
12 .panel {
13 flex-direction: row;
14 }
15}
16
17/* Portrait: height > width */
18/* Landscape: width > height */

prefers-color-scheme

Respects the user's system preference for light or dark color scheme. This is essential for creating themes that match the OS setting.

prefers-color-scheme.css
CSS
1:root {
2 --bg: #FFFFFF;
3 --text: #0D0D0D;
4 --border: #E0E0E0;
5}
6
7@media (prefers-color-scheme: dark) {
8 :root {
9 --bg: #0D0D0D;
10 --text: #E0E0E0;
11 --border: #222222;
12 }
13}
14
15/* Terminal always uses dark, but respects color palette */
16.terminal {
17 background: #0D0D0D;
18 color: #00FF41;
19}
20
21@media (prefers-color-scheme: light) {
22 .terminal {
23 border-color: #00FF41;
24 box-shadow: 0 0 20px rgba(0, 255, 65, 0.1);
25 }
26}
preview

prefers-reduced-motion

Respects the user's system preference for reduced motion. This is critical for accessibility — many users experience motion sickness or vestibular disorders triggered by animations.

prefers-reduced-motion.css
CSS
1.animated-element {
2 animation: slideIn 0.5s ease-out;
3}
4
5@media (prefers-reduced-motion: reduce) {
6 .animated-element {
7 animation: none;
8 opacity: 1;
9 transform: none;
10 }
11}
12
13/* Better approach: only animate when user prefers motion */
14@media (prefers-reduced-motion: no-preference) {
15 .fade-in {
16 animation: fadeIn 0.5s ease both;
17 }
18}

Other Useful Media Features

media-features-extra.css
CSS
1.element {
2 --spacing: 24px;
3}
4
5/* prefers-contrast — user wants more or less contrast */
6@media (prefers-contrast: high) {
7 .element {
8 border: 2px solid currentColor;
9 }
10}
11
12/* prefers-transparency */
13@media (prefers-reduced-transparency: reduce) {
14 .glass {
15 background: rgba(13, 13, 13, 0.95);
16 backdrop-filter: none;
17 }
18}
19
20/* prefers-color-scheme */
21@media (prefers-color-scheme: light) {
22 /* Overrides for light mode */
23}
24
25/* dynamic-range — HDR display detection */
26@media (dynamic-range: high) {
27 .hdr-content {
28 color: color(display-p3 0 1 0.5);
29 }
30}
31
32/* pointer — coarse/fine pointing device */
33@media (pointer: coarse) {
34 /* Touch devices — larger tap targets */
35 .button { min-height: 44px; }
36}
37
38@media (pointer: fine) {
39 /* Mouse/stylus — tighter targets ok */
40 .button { min-height: 32px; }
41}
42
43/* hover — can the device hover? */
44@media (hover: hover) {
45 .card:hover { transform: translateY(-4px); }
46}
47
48@media (hover: none) {
49 /* Touch devices — use active state instead */
50 .card:active { transform: scale(0.98); }
51}
Logical Operators

Media queries support logical operators for combining conditions: and (all conditions), not (negate), only (prevent older browsers), and comma-separated lists to represent OR logic.

logical-operators.css
CSS
1.panel {
2 display: flex;
3 gap: 24px;
4}
5
6/* AND — all conditions must match */
7@media (min-width: 768px) and (max-width: 1024px) {
8 .panel { gap: 16px; }
9}
10
11/* OR — comma-separated list */
12@media (max-width: 480px), (orientation: portrait) {
13 .panel { flex-direction: column; }
14}
15
16/* NOT — negate a condition */
17@media not (hover: none) {
18 .card:hover { transform: translateY(-4px); }
19}
20
21/* ONLY — prevent older browsers from applying the styles */
22@media only screen and (min-width: 768px) {
23 /* Only applies in browsers that understand media queries */
24}
25
26/* Equivalent queries */
27/* max-width: 768px is the same as width <= 768px */
28/* min-width: 768px is the same as width >= 768px */
Breakpoint Strategies

Two primary philosophies guide how you structure media queries: mobile-first (min-width) and desktop-first (max-width). The choice affects how styles cascade and which breakpoints you target.

Mobile-First (min-width)

Start with styles for the smallest viewports, then add layers for larger screens using min-width. This is the recommended approach because it defaults to a simple stacked layout that works everywhere, and progressively enhances for larger screens.

mobile-first.css
CSS
1.layout {
2 /* Base: single column (mobile) */
3 display: flex;
4 flex-direction: column;
5 gap: 16px;
6}
7
8/* Tablet: 2 columns */
9@media (min-width: 640px) {
10 .layout {
11 flex-direction: row;
12 flex-wrap: wrap;
13 }
14 .layout > * {
15 flex: 1 1 calc(50% - 8px);
16 }
17}
18
19/* Desktop: 3 columns */
20@media (min-width: 1024px) {
21 .layout > * {
22 flex: 1 1 calc(33.333% - 11px);
23 }
24}
25
26/* Wide: 4 columns */
27@media (min-width: 1400px) {
28 .layout > * {
29 flex: 1 1 calc(25% - 12px);
30 }
31}

Desktop-First (max-width)

Start with desktop styles, then override for smaller viewports using max-width. This can be useful when retrofitting responsive design into an existing desktop-optimized site.

desktop-first.css
CSS
1.layout {
2 /* Base: 3 columns (desktop) */
3 display: grid;
4 grid-template-columns: repeat(3, 1fr);
5 gap: 24px;
6}
7
8/* Tablet */
9@media (max-width: 1024px) {
10 .layout {
11 grid-template-columns: repeat(2, 1fr);
12 gap: 16px;
13 }
14}
15
16/* Mobile */
17@media (max-width: 640px) {
18 .layout {
19 grid-template-columns: 1fr;
20 gap: 12px;
21 }
22}

best practice

Mobile-first with min-width is the recommended approach. It reduces specificity conflicts and ensures a usable base layout on all devices, even those that do not support media queries (feature phones, very old browsers).
Common Breakpoints

While breakpoints should be determined by your content — not specific devices — there are commonly referenced viewport widths that correspond to broad device categories.

BreakpointTargetTypical Devices
320px-480pxMobile phonesiPhone SE, small Android phones
481px-768pxLarge phones / small tabletsiPhone Pro Max, iPad Mini portrait
769px-1024pxTabletsiPad portrait, small laptops
1025px-1366pxSmall laptops13" MacBook, Chromebooks
1367px-1920pxDesktop / large monitors27" monitors, iMac
1921px+Ultra-wide / 4KCinema displays, multi-monitor setups
common-breakpoints.css
CSS
1.content {
2 max-width: 1200px;
3 margin: 0 auto;
4 padding: 24px;
5}
6
7/* Mobile-first breakpoints using custom properties */
8:root {
9 --bp-sm: 640px;
10 --bp-md: 768px;
11 --bp-lg: 1024px;
12 --bp-xl: 1280px;
13 --bp-2xl: 1536px;
14}
15
16/* SM: 640px+ */
17@media (min-width: 640px) { /* ... */ }
18/* MD: 768px+ */
19@media (min-width: 768px) { /* ... */ }
20/* LG: 1024px+ */
21@media (min-width: 1024px) { /* ... */ }
22/* XL: 1280px+ */
23@media (min-width: 1280px) { /* ... */ }
24/* 2XL: 1536px+ */
25@media (min-width: 1536px) { /* ... */ }

info

Do not target specific devices with breakpoints. Instead, add a breakpoint when the layout starts to look cramped or stretched — let the content determine the breakpoints, not the device catalog. This approach is called content-based breakpoints.
Container Queries vs Media Queries

Container queries are a more recent addition to CSS that allow styling based on the size of a parent container rather than the viewport. While media queries respond to the global viewport size, container queries enable truly reusable components that adapt to their placement context.

container-vs-media.css
CSS
1.card-container {
2 container-type: inline-size;
3 container-name: card;
4}
5
6/* Media query — responds to viewport */
7@media (min-width: 768px) {
8 .card { flex-direction: row; }
9}
10
11/* Container query — responds to parent container */
12@container card (min-width: 400px) {
13 .card {
14 flex-direction: row;
15 }
16}
17
18/* Comparison: same component, different contexts */
19/*
20 Media query: .card is row when viewport > 768px
21 Container: .card is row when its parent > 400px
22 The container query makes .card truly reusable —
23 it adapts to wherever it is placed, not just viewport
24*/
AspectMedia QueriesContainer Queries
ScopeViewport / deviceParent container
ReusabilityLimited — component locked to viewportFull — component adapts to any context
Browser supportUniversalModern browsers (2023+)
Use casePage-level layoutComponent-level layout
📝

note

Container queries do not replace media queries — they complement them. Use media queries for page-level layouts (header, footer, sidebar) and container queries for reusable components (cards, widgets, lists) that need to work in multiple contexts.
Best Practices
Use mobile-first (min-width) approach — it degrades gracefully on all devices
Let content determine breakpoints — not specific device sizes
Use CSS custom properties to centralize breakpoint values
Combine prefers-color-scheme with CSS custom properties for clean theme switching
Always respect prefers-reduced-motion for accessible animations
Use hover and pointer queries to differentiate touch vs mouse interactions
Test media queries at real breakpoints — not just in DevTools responsive mode
Avoid too many breakpoints — 3-5 is usually sufficient for most layouts
Comma-separate queries for OR logic instead of duplicating style blocks
Use container queries for reusable components that need to adapt to their container
$Blueprint — Engineering Documentation·Section ID: CSS-27·Revision: 1.0