CSS Tutorial

CSS Media Queries

@media tests viewport, pointer, or preference and swaps rules. Mobile-first min-width is the usual pattern.

Rules that only apply sometimes

A stylesheet does not have to be one set of declarations for every screen. @media wraps extra rules that apply when a test is true: the viewport is at least 40rem wide, the pointer is coarse, the user asked for less motion. Outside the block, the base styles still run.

Harbor studio’s desk grid is one column on a phone and three on a desk. The HTML does not change. The media query swaps grid-template-columns. That is the whole idea.

Mobile-first min-width

Write the narrow layout first, with no query. Then add @media (min-width: …) blocks that enhance as the viewport grows. You never fight a desktop layout back down to a phone. Each query only adds what extra space allows.

max-width queries do the opposite: desktop first, then carve exceptions for small screens. That works, but you end up undoing columns, hover-only menus, and wide padding. Beginners should start with min-width.

FeatureExample testWhen it is true
Viewport width(min-width: 40rem)Layout viewport is at least 40rem
Viewport width(max-width: 39.99rem)Narrower than 40rem — desktop-first
Pointer(hover: hover)A fine pointer that can hover
Motion(prefers-reduced-motion: reduce)The user asked to cut animation
Scheme(prefers-color-scheme: dark)OS dark theme

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  .desks {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.65rem;
  }
  .desk {
    padding: 0.8rem 1rem;
    background: #fff;
    border: 1px solid #7dd3fc;
    border-radius: 0.5rem;
  }
  h2 { margin: 0 0 0.25rem; font-size: 1rem; color: #0d9488; }
  p { margin: 0; color: #475569; font-size: 0.9rem; }
  @media (min-width: 36rem) {
    .desks { grid-template-columns: 1fr 1fr 1fr; }
  }
</style>
<h1>Harbor studio</h1>
<p>One column by default. Three columns when the preview is at least 36rem wide.</p>
<div class="desks">
  <article class="desk"><h2>Tide</h2><p>Window</p></article>
  <article class="desk"><h2>Pier</h2><p>Quiet</p></article>
  <article class="desk"><h2>Loft</h2><p>Pair</p></article>
</div>

Prefer rem in the query so the breakpoint scales with root type. A 600px query stays 600 pixels when the visitor enlarges text; a 37.5rem query moves with them. Resize the pane at/css/try to cross 36rem.

Layering breakpoints

You can stack several min-width blocks. Each one should only add or replace what that width needs. Do not copy the entire stylesheet into every query. Override the two or three properties that change.

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  .page {
    display: grid;
    gap: 0.75rem;
  }
  header {
    padding: 0.75rem 1rem;
    background: #0ea5e9;
    color: #fff;
    border-radius: 0.45rem;
  }
  main, aside {
    padding: 0.85rem 1rem;
    border-radius: 0.45rem;
  }
  main { background: #fff; border: 1px solid #bae6fd; }
  aside { background: #ccfbf1; }
  h1, h2 { margin: 0 0 0.3rem; font-size: 1.05rem; }
  p { margin: 0; }
  @media (min-width: 28rem) {
    header { padding: 1rem 1.25rem; }
  }
  @media (min-width: 44rem) {
    .page { grid-template-columns: 1fr 11rem; }
    header { grid-column: 1 / -1; }
  }
</style>
<div class="page">
  <header><h1>Harbor studio</h1></header>
  <main><h2>Print shop</h2><p>Stacked on small screens. Sidebar from 44rem.</p></main>
  <aside><p>Open 8–16</p></aside>
</div>

Below 44rem the page is a single column: header, main, aside in source order. From 44rem the template becomes two columns and the header spans both with grid-column: 1 / -1.

Not only width

Width is the query you will write most. Pointer and preference queries stop you from designing only for a mouse on a large, still screen. Hover styles that reveal essential links belong behind(hover: hover), with an equivalent that is always visible on touch. Motion that is decoration should yield to prefers-reduced-motion.

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  .book {
    display: inline-block;
    padding: 0.65rem 1.1rem;
    background: #0d9488;
    color: #fff;
    border: 0;
    border-radius: 0.45rem;
    font: inherit;
    cursor: pointer;
    transition: transform 180ms ease;
  }
  @media (hover: hover) {
    .book:hover { transform: translateY(-2px); }
  }
  @media (prefers-reduced-motion: reduce) {
    .book { transition: none; }
  }
</style>
<h1>Harbor studio</h1>
<button class="book" type="button">Book a desk</button>

Combine tests with and: @media (min-width: 40rem) and (hover: hover). A comma is an or. You rarely need a long chain. One clear min-width and one preference query cover most pages.

Worked examples

The short listings above show one property. These sheets paint documents you would actually ship: a lab dashboard, a clinic form, a marks table, a nav bar.

CSS does not invent meaning. HTML already said what the pieces are. Cascade, specificity, and the box model decide how they look. The numbers are classroom values — current, pH, pulse, 3-4-5 — so the style has something real to sit on.

Preview them in the CSS editor at /css/try. Change one property and watch the page paint. The tags stay the same.

Engineering

Mobile first, then two columns

@media (min-width: 400px) adds rules when the viewport is at least that wide. Start with a stack; enhance to a grid. That is mobile-first.

prefers-color-scheme and prefers-reduced-motion are queries too. A logger that ignores reduced motion is a migraine.

Example

<style>
  .stack { display: grid; gap: 0.5rem; }
  .stack div { background: #ccfbf1; padding: 0.5rem; }
  @media (min-width: 400px) {
    .stack { grid-template-columns: 1fr 1fr; }
  }
</style>
<div class="stack"><div>Menu</div><div>Hours</div></div>

Astronomy

A sky that follows the theme

Dark scheme is a preference, not a guess. Test both. Do not ship white text that only works in dark mode.

Example

<style>
  p { color: #0f766e; }
  @media (prefers-color-scheme: dark) {
    p { color: #5eead4; }
  }
</style>
<p>Mars notes follow the theme.</p>

FAQ: CSS Media Queries

Common questions about this page.

What is the StudyGrid CSS tutorial?

The StudyGrid CSS tutorial is a full beginner track: selectors, the box model, text, layout, flex, grid, and responsive design. Each chapter has copy-and-preview examples.

Should I run css media queries examples locally for better learning?

Yes. Use the browser editor on StudyGrid for a quick check, then Download the example and run it on your computer. Local runs show real errors and the real toolchain, which is one of the fastest ways to learn css media queries in this CSS CSS lesson (CSS Media Queries).

Is the CSS editor the same as Try HTML?

No. Try CSS is a stylesheet preview at /css/try. Try HTML stays at /html/try. CSS lessons never open the HTML-only editor or the Python editor.

Do I need to install anything to learn CSS?

No. Open a chapter, click Try it in CSS, and the page preview updates in the browser.

Where should I start the CSS tutorial?

Start at CSS Intro, then Syntax, Selectors, and How To. After colors and the box model, continue to flex, grid, and media queries. Use Next at the bottom of each chapter.

Is the CSS tutorial free?

Yes. The CSS studio on StudyGrid (studygrid.in) is free: dashboard, chapters, and the live preview editor.