Media Queries and Breakpoints

Introduction

Fluid layout patterns solve many responsive problems, but not all of them. At some viewport ranges, typography, navigation, spacing, or component structure still needs explicit adaptation. This chapter explains media query syntax, breakpoint strategy, and a maintainable mobile-first workflow for real-world CSS.

Prerequisites

  • Responsive design basics
  • Familiarity with CSS units and fluid sizing
  • Basic Grid and Flexbox usage

What Media Queries Do

Media queries let you apply CSS conditionally based on environment characteristics, most commonly viewport width.

Basic syntax:

css
@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}

Meaning:

  • apply enclosed styles only when condition is true
  • min-width: 768px means this block activates at 768px and above
  • max-width: 720px keeps long lines readable on larger screens

Most responsive work uses width conditions, but media queries can also target print, orientation, and user preferences.

Mobile-First with min-width

Recommended approach:

  1. write base styles for small screens
  2. progressively enhance with min-width breakpoints

Example:

css
.nav {
  display: grid;
  gap: 0.5rem;
}
 
@media (min-width: 768px) {
  .nav {
    display: flex;
    align-items: center;
    gap: 1rem;
  }
}

Why this works well:

  • smaller defaults stay simple
  • larger screens get additive enhancements
  • fewer override conflicts

Code explanation:

  • base .nav uses grid for compact mobile stacking
  • at 768px+, layout switches to flex for horizontal alignment
  • align-items: center vertically aligns nav content
  • gap increases from 0.5rem to 1rem for desktop breathing room

max-width Queries

max-width is also valid:

css
@media (max-width: 767px) {
  .sidebar {
    display: none;
  }
}

Use carefully:

  • excessive max-width patches can become hard to maintain

Code explanation:

  • condition applies only at 767px and below
  • display: none removes sidebar from layout entirely on small screens
  • this is useful for dense secondary panels, but ensure navigation still remains accessible

In most teams, mobile-first + min-width is easier long-term.

Common Breakpoint Ranges (Guideline)

Project-specific breakpoints vary, but a common pattern is:

  • base: mobile-first default
  • @media (min-width: 600px) for larger phones/small tablets
  • @media (min-width: 900px) for tablet/desktop transition
  • @media (min-width: 1200px) for wide desktop refinements

These are starting points, not strict standards.

Tip

Break on Content, Not Device Names

Add a breakpoint where layout quality drops, not because a specific phone model exists.

Organizing Breakpoints in CSS

Two common patterns:

  1. Component-local queries: keep media rules near component styles
  2. Centralized breakpoint sections: group all responsive rules by width

For most modern codebases, component-local organization is easier to read and maintain.

Example:

Code explanation:

  • mobile default is a single-column list (1fr)
  • at 700px+, it becomes 2 columns with repeat(2, 1fr)
  • at 1024px+, it expands to 3 columns
  • this is a classic progressive enhancement breakpoint pattern

Combining Conditions

You can combine conditions with and:

css
@media (min-width: 768px) and (max-width: 1023px) {
  .banner {
    padding: 1.5rem;
  }
}

Useful for targeted tuning in a middle range.

Code explanation:

  • both conditions must be true (and)
  • this targets the medium range only (roughly tablet width)
  • only .banner padding is tuned, keeping the override narrowly scoped

Avoid over-fragmenting into many tiny ranges unless truly needed.

Orientation Queries

Orientation can be useful for specific UI elements:

css
@media (orientation: landscape) {
  .hero {
    min-height: 70vh;
  }
}

Do not rely only on orientation for major layout logic; width-based behavior is usually more stable.

Code explanation:

  • rule applies when viewport is wider than tall (landscape)
  • min-height: 70vh ensures hero keeps visual presence in horizontal mode
  • vh means percentage of viewport height

For print-friendly output:

css
@media print {
  nav,
  .actions,
  .ads {
    display: none;
  }
 
  body {
    color: #000;
    background: #fff;
  }
}

Useful for docs, invoices, and report pages.

Code explanation:

  • @media print runs only for print preview/printing
  • navigation/actions/ads are hidden to reduce noise
  • body colors switch to black-on-white for print readability

Preference-Based Queries

Modern media queries can respect user settings:

Reduced motion

css
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

Code explanation:

  • activates when user OS/browser requests reduced motion
  • disables transitions and animations to reduce vestibular discomfort
  • !important ensures these accessibility overrides win over component animation rules

Dark mode preference

css
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b1220;
    --text: #e2e8f0;
  }
}

These improve accessibility and user comfort.

Code explanation:

  • activates when user prefers dark mode at system level
  • updates root CSS variables (--bg, --text)
  • components using these tokens automatically switch theme without rewriting each selector

Breakpoint Token Strategy

Defining shared breakpoint tokens improves consistency across files:

css
/* Example convention (comments or preprocessor vars) */
/* sm: 600px, md: 900px, lg: 1200px */

Code explanation:

  • this block documents shared breakpoint semantics for teams
  • even without native media-query variables in plain CSS, a clear convention reduces inconsistent breakpoint usage

In plain CSS, custom properties cannot directly parameterize media query conditions in all contexts, so teams often document constants in conventions, design docs, or preprocessor config.

Common Mistakes

MistakeWhy it hurtsBetter approach
Too many breakpointsHard-to-maintain CSSStart minimal, add only where needed
Device-specific targetingQuickly outdated rulesUse content-driven width thresholds
Desktop-first overrides onlyComplex cascade conflictsUse mobile-first base + min-width enhancements
Large structural change at tiny rangeJumpy UXKeep layout transitions gradual
Ignoring real-device testingHidden usability issuesTest on at least one physical phone/tablet

Debugging Media Queries

When responsive styles do not apply:

  1. check current viewport width in DevTools
  2. confirm media condition actually matches
  3. inspect if rule is overridden by later/specific selector
  4. verify CSS file load order
  5. test by temporarily forcing the rule outside query

DevTools usually shows inactive media query blocks clearly.

Mini Exercise

  1. Create a simple page with header, nav, and card list
  2. Write mobile-first base styles
  3. Add one breakpoint at 700px for 2-column cards
  4. Add one breakpoint at 1024px for 3-column cards
  5. Add a prefers-reduced-motion block for animations
  6. Verify behavior in responsive mode and on a real mobile device

FAQ

Should I always use min-width media queries?

For mobile-first workflows, usually yes. max-width is still useful in specific patch scenarios.

How many breakpoints should a typical page have?

Often two to four well-chosen breakpoints are enough, especially with fluid layout patterns.

Can Grid/Flex replace media queries completely?

No. They reduce breakpoint needs, but media queries are still essential for structural and typographic adjustments.

Why is my media query rule visible in CSS but not applied?

Either the condition does not match current viewport, or another rule wins by specificity/order.

Prefer content-driven breakpoints. Device lists change constantly; content requirements are more stable.