MGU Computer Science Series — Web Development: HTML, CSS, and JavaScript
Part III: CSS — Style and Layout
Mobile-First · Media Queries · Relative Units · Fluid Images · Breakpoints
Chapter 17 of 30
17
MGU Computer Science Series  ·  Web Development: HTML, CSS, and JavaScript  ·  Library Textbook Edition

Chapter 17:
Responsive Design
and Media Queries

Building layouts that adapt to any screen — mobile-first thinking, relative units, fluid containers, responsive images, media queries, breakpoints, and responsive navigation

■ Part III of VII ■

■ 11 Sections  •  Chapter 17 of 30 ■

Builds on Chapters 11–16 — selectors, the cascade, typography, the box model, flexbox, and grid

Chapter Introduction and Learning Objectives

When the web was young, almost everyone browsing it sat in front of a desktop computer with a large monitor. Designers could safely assume a wide, predictable screen. That world is gone. Today the same HTML page might open on a 375-pixel phone, a 768-pixel tablet, a 1440-pixel laptop, or a 2560-pixel desktop monitor — sometimes within the same hour, on the same person's devices. A layout that only works at one of these sizes fails everywhere else.

This chapter teaches you how to build pages that adapt. You will learn why fixed, pixel-locked layouts break on small screens, how to think mobile-first instead of designing for desktop and patching mobile afterward, how to use CSS units that scale instead of units that are locked in place, how to make images resize without overflowing their containers, how to write media queries that apply different styles at different screen widths, how to choose breakpoints based on your content rather than guesswork, how to adapt navigation for narrow screens, and how to test all of it using your browser's built-in tools. By the end of the chapter, the pages you build will work as well on a phone in someone's pocket as they do on a desktop monitor across a room.

Opening Question

Imagine the same HTML file opened on three different screens: a phone 375 pixels wide, a tablet 768 pixels wide, and a desktop monitor 1440 pixels wide. With no responsive CSS at all, what happens to a three-column layout designed for the desktop width when it loads on the phone? Why does simply shrinking everything proportionally, the way a photocopier shrinks a page, not actually solve the problem? By the end of this chapter you will be able to answer both questions with specific CSS tools, not just general impressions.

11Sections
12Objectives
15Key Terms
30Total Chapters

Learning Objectives

By the end of this chapter, you should be able to:

  1. 1Explain why responsive design is necessary given the wide range of modern screen sizes.
  2. 2Describe typical viewport widths for phones, tablets, laptops, and desktop monitors.
  3. 3Explain the difference between mobile-first and desktop-first CSS, and why mobile-first is preferred.
  4. 4Use relative CSS units — em, rem, %, vw, vh, and ch — appropriately for different sizing tasks.
  5. 5Build a fluid container using width and max-width together.
  6. 6Make images responsive using max-width: 100%, height: auto, and the srcset attribute.
  7. 7Write media queries using min-width and explain other media features such as prefers-color-scheme.
  8. 8Choose breakpoints based on content behavior rather than specific device models.
  9. 9Describe a basic responsive navigation pattern, including the hamburger menu concept.
  10. 10Use browser developer tools to test a layout across multiple screen widths and orientations.
  11. 11Identify and fix common responsive layout problems, including horizontal overflow and unreadable text.
  12. 12Explain the purpose and correct syntax of the viewport meta tag.

Sections at a Glance

Sections 17.1 – 17.4
The Problem and the Mindset: Many Screens, Mobile-First, Flexible Units
Devices · Mobile-First Design · em / rem / % / vw / vh / ch

Why Responsive Design Matters

When the web was young, almost everyone who used it sat in front of a desktop computer with a large monitor. Web pages were designed for fixed, wide screens. Designers and developers could assume that a user's browser window was probably at least 800 pixels wide, and later 1024 pixels wide. Pages were built with hard-coded pixel measurements because the screen was predictable.

That world no longer exists. Today, people browse the web on smartphones, tablets, laptops, desktop monitors, smart TVs, e-readers, and devices that did not exist a decade ago. A smartphone screen might be 320 to 430 pixels wide. A tablet might be 768 to 1024 pixels. A laptop might be 1200 to 1440 pixels. A desktop with a wide monitor might be 1600 to 2560 pixels or more. No single fixed layout can serve all of these well.

Definition

Responsive design is the practice of building websites that detect and adapt to the user's screen size and environment, so that the layout, text, images, and navigation all remain readable and usable no matter where someone opens the page. The term was defined and popularized by web designer Ethan Marcotte, who described three core ingredients: fluid grids, flexible images, and media queries. These three ideas remain central today.

A website that is not responsive forces users on small screens to scroll horizontally, zoom in and out to read text, squint at tiny navigation menus, and pinch to hit buttons. These are serious usability failures. In many parts of the world, mobile devices are the primary or only way people access the web. Building a site that only works well on a large screen means excluding or frustrating a large part of the audience.

Connection to Accessibility

Responsive design is also an accessibility issue. A site that requires zooming, horizontal scrolling, or tapping tiny targets is harder to use for people with motor disabilities, vision differences, or older devices. The accessibility principles from earlier chapters and the layout principles in this one work toward the same goal: a page that anyone can use, on whatever device they have.

Different Devices and Screen Sizes

Before writing any responsive CSS, it helps to understand the range of devices that visit websites.

Device CategoryTypical Viewport WidthNotes
Mobile phones320px – 430px (portrait)375px and 390–430px are common for current phones; 320px covers older or budget devices
Tablets600px – 1024pxAbout 768–820px in portrait, 1024px or wider in landscape; varies by manufacturer
Laptops1200px – 1440pxMeasured at 100% browser zoom; some users zoom in or out, changing the effective viewport
Desktop monitors1440px – 2560px+Wide monitors can exceed 3000px; max-width containers matter most here

These numbers describe the viewport, which is the visible area of the browser window, not necessarily the full screen resolution. A user can resize their browser window, which changes the viewport. This range from 320 to 2560-plus pixels is enormous. A layout that fills a 1400-pixel screen comfortably will be completely unusable at 375 pixels if no responsive adjustments are made.

There is also the concept of pixel density. Modern devices have high-resolution retina or HiDPI screens where one CSS pixel does not correspond to one physical hardware pixel. On these screens, the browser scales content automatically, but images that are not sized appropriately may appear blurry. Section 17.6 returns to this when discussing the srcset attribute.

Mobile-First Thinking

There are two approaches to building responsive layouts. Desktop-first means you design and code the full wide-screen layout first, then add CSS to override it for smaller screens. Mobile-first means you design and code the narrow mobile layout first, then add CSS to enhance it for wider screens.

Mobile-first is the stronger approach, and it is what professional developers use by default. Writing CSS in a mobile-first way means your base styles are the simplest version of the layout: a single column, readable text, accessible buttons, no complex positioning. This is correct behavior for small screens. Then, as the screen gets wider, you layer in enhancements using media queries.

This is technically cleaner because you are progressively adding complexity rather than trying to undo complexity. It is also easier to maintain because the fallback behavior — what happens on the smallest screen, or in the least capable browser — is always the base stylesheet, which is simple and reliable. Desktop-first thinking often produces code where the base styles contain a complex multi-column layout, and the developer has to override many properties at smaller breakpoints to collapse everything back to a single column. This leads to more overrides, more specificity conflicts, and harder debugging.

Example 17.3.1
The same layout, two approaches
  • Mobile-firstBase styles stack three cards vertically with flex-direction: column. A min-width: 768px media query switches to flex-direction: row. The simplest case is the default; complexity is added only when there is room for it.
  • Desktop-firstBase styles lay out three cards horizontally with flex-direction: row. A max-width: 767px media query overrides back to flex-direction: column. The complex case is the default, and the simple case is an override.
  • Why it mattersBoth approaches can render identically, but as a project grows, mobile-first produces fewer overrides and cleaner code, and it matches how most real users — many of them on phones — actually meet your site first.
CSS — Mobile-First
/* Base styles: cards stack vertically on mobile */
.card-row {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* At wider screens, switch to horizontal row */
@media (min-width: 768px) {
  .card-row {
    flex-direction: row;
  }
}
CSS — Desktop-First (Not Recommended as the Default Habit)
/* Base styles: three columns on desktop */
.card-row {
  display: flex;
  flex-direction: row;
  gap: 1.5rem;
}

/* At narrow screens, override to stack */
@media (max-width: 767px) {
  .card-row {
    flex-direction: column;
  }
}
Study Note

All examples in this chapter follow the mobile-first approach: base styles target the narrowest screens, and min-width media queries layer in enhancements as the viewport widens.

Relative Units

A key tool of responsive design is using units that scale with the user's environment instead of units fixed at a specific number of pixels.

Pixels as a Fixed Unit

The px unit in CSS is an absolute unit tied to a specific physical size, calibrated to the device. On most screens, 16px is the default browser body font size. However, pixels do not scale when users change their browser zoom level or default font size. If a user has set their browser font size to 20px for readability, font-size: 16px ignores that preference and forces the smaller size. This is an accessibility concern. Pixels are also inflexible for layout: a column that is 600px wide will overflow a 375px phone screen.

The em Unit

The em unit is relative to the font size of the current element. If an element has font-size: 20px, then 1em equals 20px within that element, 2em equals 40px, and 0.5em equals 10px. em units are useful for spacing that should scale proportionally with text, such as padding inside buttons. However, em values can compound when elements are nested, which makes them harder to reason about across deep nesting.

The rem Unit

The rem unit stands for root em. It is relative to the font size of the root element — the html element. Since the default browser body font size is typically 16px, 1rem equals 16px on most browsers. Unlike em, rem does not compound through nesting: 1rem always means the same thing no matter how deep inside the HTML the element lives. rem also respects browser font size preferences, which is important for accessibility.

CSS — Using rem for Consistent, Accessible Sizing
body {
  font-size: 1rem;       /* 16px at default browser settings */
  line-height: 1.6;
}

h1 {
  font-size: 2rem;       /* 32px at default */
  margin-bottom: 1rem;
}

p {
  font-size: 1rem;
  margin-bottom: 1rem;
}

.button {
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
}

The Percentage Unit

Percentage units are relative to the parent element's size. width: 50% means the element takes up half its parent's width. This is useful for fluid layouts where elements should fill available space proportionally.

CSS
.container {
  width: 90%;        /* 90% of the viewport width */
  max-width: 1200px; /* but never wider than 1200px */
  margin: 0 auto;    /* centered */
}

Viewport Units

Viewport units are relative to the viewport size — the visible browser area. vw is one percent of the viewport width; 100vw is the full width. vh is one percent of the viewport height; 100vh is the full height. Viewport units are useful for full-screen sections, hero images, and large typographic elements.

CSS
/* A hero section that fills the full viewport height */
.hero {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Large display text that scales with the screen */
.display-text {
  font-size: 5vw;
}
Caution

Be careful with vw on text. 5vw on a 1400px screen produces 70px text, which may suit a hero heading. On a 375px phone, 5vw produces only 18.75px, which may also be fine — but check the result on both ends of the range. Very small or very large vw values on text can produce unreadably tiny or disproportionately large text.

The ch Unit

The ch unit is equal to the width of the 0 character in the current font. This is surprisingly useful for setting readable line widths. A comfortable reading line is generally between 45 and 75 characters wide. max-width: 65ch on a paragraph container creates a readable measure that also scales with the font size.

CSS
.article-body p {
  max-width: 65ch;
}

Choosing the Right Unit

UnitBest Used For
remFont sizes, spacing, and most general sizing. Scales with browser preferences.
%Widths of containers and layout elements that should fill available space.
pxFine details like borders, shadows, or very small decorative sizes needing pixel precision.
vw / vhFull-screen sections, hero areas, and viewport-sized containers.
emSpacing directly tied to local text size, such as padding inside a component.
chReadable maximum line lengths for body text.
Sections 17.5 – 17.8
The Tools: Fluid Containers, Responsive Images, Media Queries, Breakpoints
max-width Pattern · srcset · @media · Choosing Breakpoints

max-width and Fluid Containers

A fundamental tool of responsive layout is the pattern of setting a fluid width with a maximum cap. Without any responsive thinking, you might write width: 1200px. This works on wide screens, but on a 375px phone the container overflows the viewport by 825 pixels. The page becomes unusable.

CSS — A Fluid, Capped Container
.container {
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
}

This container takes up 90% of the available width — which on a phone is 90% of 375px, giving roughly 338px — but grows no wider than 1200px on large screens. The margin: 0 auto centers it horizontally. This pattern is the foundation of almost every responsive layout: the container is always fluid and proportional, but never so wide that it becomes hard to read on large monitors.

Why max-width Instead of width

Setting width: 1200px locks the element at exactly 1200px. Setting max-width: 1200px allows the element to be narrower than 1200px when the screen is smaller, while still preventing it from growing beyond 1200px on wide screens. This is the difference between a fixed layout and a fluid one.

CSS — Blocking vs. Enabling Responsive Behavior
/* This blocks responsive behavior */
.container {
  width: 1200px;  /* never changes */
}

/* This enables responsive behavior */
.container {
  width: 100%;       /* takes all available space */
  max-width: 1200px; /* but no wider than this */
  padding: 0 1.5rem; /* horizontal breathing room */
  margin: 0 auto;    /* centered */
}

The padding: 0 1.5rem adds horizontal padding so that on a small screen the text does not press directly against the edges of the screen. This is an important usability detail that is easy to forget.

Responsive Images

Images are one of the most common places where layouts break on small screens. An image that is 800 pixels wide will overflow a 375-pixel phone if no CSS handles it.

The Fluid Image Rule

The simplest and most important rule for responsive images is:

CSS — The Fluid Image Rule
img {
  max-width: 100%;
  height: auto;
  display: block; /* prevents small gap below image in some browsers */
}

max-width: 100% prevents an image from growing wider than its container. On a phone where the container is 338px, a 1200px image will scale down to 338px. height: auto keeps the aspect ratio correct as the width changes, so the image does not appear squashed or stretched. Many developers include this rule in their global base styles so it applies to every image on every page automatically.

The width and height Attributes in HTML

It is good practice to include width and height attributes on img elements in your HTML, even when CSS is controlling the display size. These attributes let the browser reserve the correct amount of space in the layout before the image loads, preventing a visual jump known as layout shift.

HTML
<img
  src="images/hero.jpg"
  alt="Students working together at a library table"
  width="1200"
  height="600"
>

The HTML attributes define the aspect ratio. The CSS can still override the display size, but the browser uses the ratio from the attributes to hold space correctly.

High-Resolution Screens and the srcset Attribute

On high-resolution (retina or HiDPI) screens, a single image displayed at a given CSS pixel size may look blurry if the image file itself does not have enough pixels. A screen with a 2x pixel ratio needs twice as many image pixels per CSS pixel to look sharp. The srcset attribute on img allows the browser to choose from a list of image sources based on the screen's pixel density or the available layout width.

At an introductory level, the two-image version is the most practical:

HTML
<img
  src="images/photo-800.jpg"
  srcset="images/photo-800.jpg 1x, images/photo-1600.jpg 2x"
  alt="A courtyard with trees and benches"
  width="800"
  height="450"
>

The browser uses photo-800.jpg on standard displays and photo-1600.jpg on high-resolution displays. This improves visual quality without forcing every user to download a larger file. A deeper treatment of srcset with width descriptors and sizes attributes is a topic for more advanced study, but the 1x/2x pattern is a practical starting point.

Background Images

Background images set with CSS, such as background-image: url(...), also need responsive attention. They can be sized with background-size: cover to fill their container regardless of size, which is the most common technique for hero background images.

CSS
.hero {
  background-image: url("images/hero-background.jpg");
  background-size: cover;
  background-position: center;
  height: 60vh;
}
Study Note

background-size: cover ensures the image always covers the entire container, cropping if necessary, but never leaving empty space. This works well for decorative backgrounds, though important content should not be embedded inside images used as backgrounds — screen readers cannot read text baked into an image.

Media Queries

A media query is a CSS rule that applies certain styles only when specific conditions about the user's device or browser environment are true. The most common use of media queries is to detect viewport width and apply different layout styles at different sizes. This is the core mechanism of responsive CSS.

CSS — Basic Syntax
@media (condition) {
  /* Styles that apply only when the condition is true */
}

The most important condition for layout is min-width for mobile-first design, or max-width for desktop-first. Mobile-first uses min-width, which means "apply these styles when the viewport is at least this wide":

CSS
/* Base styles apply to all screens (mobile first) */
.nav-links {
  display: none; /* hidden on mobile */
}

/* At 768px and wider, show the navigation */
@media (min-width: 768px) {
  .nav-links {
    display: flex;
  }
}

Inside a Media Query

Everything inside the @media block is normal CSS. Selectors, properties, values — they all work exactly as in the rest of your stylesheet. The media query is just a condition wrapper.

CSS
/* Mobile base: single column layout */
.content-grid {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.sidebar {
  background-color: var(--color-surface);
  padding: 1.5rem;
  border-radius: 8px;
}

/* Tablet and above: two-column layout */
@media (min-width: 768px) {
  .content-grid {
    flex-direction: row;
  }

  .sidebar {
    width: 280px;
    flex-shrink: 0;
  }
}

/* Wide desktop: adjust spacing */
@media (min-width: 1200px) {
  .content-grid {
    gap: 3rem;
  }
}

Media Query Location in Your Stylesheet

There are two common ways to organize media queries. One approach places all media queries together at the bottom of the stylesheet, grouped by breakpoint. Another approach places media queries directly after the base styles for each component they modify. Both are valid. For beginners, grouping media queries near the styles they modify makes it easier to understand what changes at each breakpoint.

CSS — Component-Adjacent Organization
/* Navigation */
.nav {
  display: flex;
  align-items: center;
  padding: 1rem var(--space-page-padding);
  background-color: var(--color-nav-bg);
}

.nav-menu {
  display: none;       /* hidden hamburger area on mobile */
  gap: 2rem;
}

.nav-hamburger {
  display: block;      /* visible on mobile */
  cursor: pointer;
}

@media (min-width: 768px) {
  .nav-menu {
    display: flex;     /* show full menu on tablet and above */
  }

  .nav-hamburger {
    display: none;     /* hide hamburger button on tablet and above */
  }
}

Other Media Query Conditions

min-width and max-width are the most commonly used conditions, but media queries can test other things. orientation: portrait matches when the height is greater than the width; orientation: landscape matches when the width is greater than the height.

CSS
@media (orientation: landscape) {
  .hero {
    height: 50vh; /* shorter in landscape to leave room for content */
  }
}

prefers-color-scheme: dark matches when the user's operating system is set to dark mode.

CSS
@media (prefers-color-scheme: dark) {
  :root {
    --color-background: #1a1a2e;
    --color-text: #e8e8f0;
    --color-surface: #2a2a3e;
  }
}

prefers-reduced-motion: reduce matches when the user has requested less motion or animation in their system settings.

CSS
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
Connection to Accessibility

These preference-based media queries are important for accessibility. Respecting a user's system settings — their color preference, their motion tolerance — is a form of inclusive design that costs only a few lines of CSS.

Breakpoints

A breakpoint is a specific viewport width at which your layout changes in a meaningful way. A breakpoint is the value you put inside min-width or max-width in a media query.

Common Breakpoints

There is no universal list of required breakpoints. Breakpoints should be chosen based on where your specific content needs to change, not based on matching specific device models. That said, the following ranges are commonly useful as starting points:

RangeLabelTypical Use
Below 600pxSmall mobileBase mobile styles
600px – 767pxLarge mobile / small tabletSometimes a distinct step
768px – 1023pxTabletTwo-column layouts, expanded navigation
1024px – 1279pxSmall laptopWider containers, more columns
1280px and aboveDesktopFull multi-column layouts
1440px and aboveWide desktopMax-width containers become visible

These numbers are not locked. Your project might only need two or three breakpoints. A simpler site with clean semantic HTML and a fluid container might only need one or two media queries.

Choosing Breakpoints by Content, Not by Device

The most reliable way to find the right breakpoints for your layout is to resize your browser window and watch your content. When the layout starts to look uncomfortable — when text gets too narrow or too wide, when columns become cramped, when navigation items start crowding — add a breakpoint there. Do not add breakpoints just because a popular device has a certain width. Add them because your content needs them.

CSS — A Project That Only Needs Two Breakpoints
/* Base: single column, narrow screens */
.layout {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 1rem;
}

/* Two columns when there is room */
@media (min-width: 720px) {
  .layout {
    flex-direction: row;
    padding: 2rem;
  }
}

/* Widen the container and add more spacing */
@media (min-width: 1100px) {
  .layout {
    gap: 3rem;
    padding: 2rem 4rem;
  }
}
Avoiding Breakpoint Proliferation

Some developers add many breakpoints — targeting every device size they can think of — and end up with a stylesheet that is difficult to maintain. It is better to have three thoughtful breakpoints that cover most users well than to have fifteen breakpoints that each adjust tiny details. Start with one or two breakpoints and add more only when the content clearly needs them.

Sections 17.9 – 17.11
Putting It Together: Navigation, Testing, and the Viewport Tag
Hamburger Menu · Developer Tools · <meta name="viewport">

Responsive Navigation at an Introductory Level

Navigation is one of the most design-challenging areas of responsive layout. On a desktop, a row of navigation links fits comfortably in a header bar. On a phone with a 375px screen, that same row of links may not fit at all.

The most common solution is the hamburger menu: on small screens, navigation links are hidden behind a button — often represented by three horizontal lines (☰) — which is why it is called a hamburger. Pressing the button reveals the navigation. A full hamburger menu requires JavaScript to toggle visibility, which is covered in Chapter 27. Here, the focus is on the CSS structure that makes navigation responsive — hiding and showing elements at the right sizes.

The Basic Responsive Navigation Structure

HTML
<header class="site-header">
  <div class="header-inner">
    <a href="index.html" class="site-logo">Learning Site</a>

    <button class="nav-toggle" aria-expanded="false" aria-label="Open navigation">
      &#9776; <!-- hamburger icon character -->
    </button>

    <nav class="main-nav" id="main-nav">
      <ul class="nav-list">
        <li><a href="index.html">Home</a></li>
        <li><a href="about.html">About</a></li>
        <li><a href="lessons.html">Lessons</a></li>
        <li><a href="resources.html">Resources</a></li>
        <li><a href="contact.html">Contact</a></li>
      </ul>
    </nav>
  </div>
</header>
CSS — Responsive Behavior
.site-header {
  background-color: var(--color-header-bg);
  padding: 0 1.5rem;
  position: sticky;
  top: 0;
  z-index: 100;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
  max-width: 1200px;
  margin: 0 auto;
}

.site-logo {
  font-size: 1.25rem;
  font-weight: 700;
  text-decoration: none;
  color: var(--color-text);
}

/* Mobile: navigation is hidden by default */
.main-nav {
  display: none;
  position: absolute;
  top: 64px;
  left: 0;
  right: 0;
  background-color: var(--color-header-bg);
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--color-border);
}

/* When JavaScript adds this class, show the nav */
.main-nav.is-open {
  display: block;
}

.nav-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.nav-list a {
  display: block;
  padding: 0.5rem 0;
  text-decoration: none;
  color: var(--color-text);
}

/* Hamburger button visible on mobile */
.nav-toggle {
  display: block;
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--color-text);
  padding: 0.5rem;
}

/* Tablet and above: show full navigation, hide hamburger */
@media (min-width: 768px) {
  .main-nav {
    display: block;           /* always visible */
    position: static;         /* not absolutely positioned */
    padding: 0;
    border-top: none;
    background-color: transparent;
  }

  .nav-list {
    flex-direction: row;      /* horizontal row */
    gap: 2rem;
  }

  .nav-toggle {
    display: none;            /* hide hamburger */
  }
}

The JavaScript to toggle the menu open and closed is added in Chapter 27. The CSS above defines both states: the hidden-by-default mobile state and the always-visible desktop state.

Accessible Markup from the Start

Notice that the HTML uses aria-expanded="false" on the toggle button. This attribute communicates to screen readers whether the navigation is open or closed. JavaScript should update it to "true" when the menu is open. Building this attribute into the markup now, even before the interactive behavior exists, means the accessible structure is correct from the start.

Testing Responsive Layouts

Building a responsive layout without testing it at different sizes is like building a bridge without measuring. Testing is not optional, and it does not have to be complicated.

Browser Developer Tools: Responsive View

Every major browser's developer tools include a responsive preview mode. In Chrome, Firefox, and Edge, you can open the developer tools and click the device toolbar icon (or press Ctrl+Shift+M on Windows/Linux, Cmd+Shift+M on macOS). In this mode, you can set a specific pixel width by typing a number, drag the edge of the preview to resize freely while watching the layout adjust, select from a list of preset device sizes, change orientation between portrait and landscape, and toggle the display pixel ratio to simulate retina screens.

This is the fastest and most reliable way to test a responsive layout during development. Resize the window slowly from narrow to wide, watching carefully for any point where the layout breaks, text overflows, or elements collide.

What to Check

Testing Checklist
Work through this checklist at each major width
  • 320–375pxDoes all content fit without horizontal scrolling? Is text readable without zooming? Are tap targets at least 44px by 44px? Does navigation work? Do images scale? Is the layout single-column and uncluttered?
  • 600–768pxDo any layout shifts apply correctly? Does the transition from mobile to tablet layout feel natural?
  • 768–1024pxDoes the full navigation appear? Do multi-column layouts work without cramping? Is content proportioned well?
  • 1200–1440pxIs the container centered and well-proportioned? Does the max-width cap the layout appropriately? Is there enough whitespace?
  • 1600px+Does the max-width container prevent text lines from becoming too long? Is the page balanced, not just tiny content in the middle of a huge screen?

Real Device Testing

Developer tools responsive mode is very helpful, but it does not perfectly replicate how a real phone renders a page. When possible, test on at least one actual smartphone by opening your site on the local network. Browsers on real devices sometimes render fonts, scrolling, and touch targets differently from what the desktop simulation shows. A common method: start a local development server, find your computer's local IP address, and type that address in your phone's browser, making sure both devices share the same Wi-Fi network.

Common Responsive Layout Problems

ProblemLikely Cause
Horizontal scrolling on mobileAn element with a fixed pixel width wider than the viewport, or content with overflow: visible extending off-screen. Try overflow-x: hidden on body to confirm, then find and fix the source element.
Text too small to readFont sizes set too small in the base stylesheet, or px-based font sizes that fail to scale with user preferences.
Images overflowing their containermax-width: 100%; height: auto not applied to img.
Navigation breaking at certain widthsThe breakpoint value does not match where the navigation naturally starts to overflow.
Content cut off on mobileA fixed-width parent element that does not resize with the viewport.

The Viewport Meta Tag

The viewport meta tag is a critical piece of HTML that is required for responsive design to work correctly on mobile devices.

HTML
<meta name="viewport" content="width=device-width, initial-scale=1.0">

Without this tag, mobile browsers shrink the entire page down to simulate a desktop viewport — typically around 980 pixels wide — and then display it at that tiny size, leaving the user to zoom in. This behavior comes from the early days of smartphones, when websites were not designed for small screens and mobile browsers tried to helpfully display them anyway by shrinking everything.

With this tag, you are telling the browser: this page is designed for mobile, set the viewport width to the actual device width, and display at 1:1 scale without zooming. width=device-width sets the viewport width to the physical width of the device. initial-scale=1.0 sets the initial zoom level to 100%.

Why This Tag Is Not Optional

Without this tag, your media queries will still fire at their min-width values — but based on the simulated desktop viewport, not the real device width. Your beautifully crafted mobile layout at 375px will never appear on a real iPhone because the browser thinks it is operating at 980px. The viewport meta tag is what makes CSS media queries respond to the real device width. Every responsive HTML document should have this tag in the <head>. It is included in the standard HTML skeleton taught in Chapter 5.

Never Disable Zoom

Some developers add user-scalable=no to the viewport meta tag to prevent zooming: content="width=device-width, initial-scale=1.0, user-scalable=no". This is incorrect and should never be done. Users who need to zoom in — including people with low vision — have the right to do so. Disabling zoom is an accessibility violation, not a design choice.

Building a Responsive Page

Let us work through building a page that combines responsive principles from this chapter: a simple page with a sticky header, a hero section, a three-card content section, and a footer. On mobile, the cards stack vertically. On tablets and above, they display in a row.

The HTML

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Page Example</title>
  <link rel="stylesheet" href="css/main.css">
</head>
<body>

  <header class="site-header">
    <div class="header-inner">
      <a href="index.html" class="site-logo">Learning Site</a>
      <nav class="main-nav" aria-label="Main navigation">
        <ul class="nav-list">
          <li><a href="index.html">Home</a></li>
          <li><a href="about.html">About</a></li>
          <li><a href="lessons.html">Lessons</a></li>
          <li><a href="contact.html">Contact</a></li>
        </ul>
      </nav>
    </div>
  </header>

  <main>

    <section class="hero">
      <div class="hero-inner">
        <h1>Learn at Your Own Pace</h1>
        <p>Resources, guides, and lessons for curious students.</p>
        <a href="lessons.html" class="button-primary">Browse Lessons</a>
      </div>
    </section>

    <section class="features">
      <div class="container">
        <h2>What You Will Find</h2>
        <div class="card-row">
          <article class="card">
            <h3>Lessons</h3>
            <p>Step-by-step guides on web development, programming, and computer science foundations.</p>
          </article>
          <article class="card">
            <h3>Resources</h3>
            <p>Curated links, references, and tools for every topic in the curriculum.</p>
          </article>
          <article class="card">
            <h3>Projects</h3>
            <p>Hands-on mini-projects that practice skills in real, practical contexts.</p>
          </article>
        </div>
      </div>
    </section>

  </main>

  <footer class="site-footer">
    <div class="container">
      <p>&copy; 2025 Learning Site. All rights reserved.</p>
    </div>
  </footer>

</body>
</html>
Notice

The viewport meta tag is present in the <head>. This is essential for responsive design and was covered in Section 17.11.

The CSS

CSS
/* =========================================
   CSS Variables (Chapter 18 preview)
   ========================================= */
:root {
  --color-background: #ffffff;
  --color-text: #1a1a2e;
  --color-text-muted: #555566;
  --color-surface: #f4f4f8;
  --color-border: #dddde8;
  --color-header-bg: #ffffff;
  --color-hero-bg: #1a1a2e;
  --color-hero-text: #ffffff;
  --color-primary: #4a6cf7;
  --color-primary-hover: #3a5ce7;

  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2rem;
  --space-xl: 3rem;

  --page-padding: 1.25rem;
  --container-max: 1200px;
}

/* =========================================
   Base / Reset
   ========================================= */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--color-text);
  background-color: var(--color-background);
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--color-primary);
}

/* =========================================
   Utility
   ========================================= */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--page-padding);
}

/* =========================================
   Header
   ========================================= */
.site-header {
  background-color: var(--color-header-bg);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 100;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 60px;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--page-padding);
}

.site-logo {
  font-size: 1.125rem;
  font-weight: 700;
  text-decoration: none;
  color: var(--color-text);
}

/* Navigation: simplified version without hamburger for this example */
.nav-list {
  list-style: none;
  display: flex;
  gap: var(--space-lg);
}

.nav-list a {
  text-decoration: none;
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  transition: color 0.2s ease;
}

.nav-list a:hover {
  color: var(--color-primary);
}

/* On mobile, hide the nav list for simplicity in this base example */
.main-nav {
  display: none;
}

@media (min-width: 640px) {
  .main-nav {
    display: block;
  }
}

/* =========================================
   Hero Section
   ========================================= */
.hero {
  background-color: var(--color-hero-bg);
  color: var(--color-hero-text);
  padding: var(--space-xl) var(--page-padding);
  text-align: center;
}

.hero-inner {
  max-width: 680px;
  margin: 0 auto;
}

.hero h1 {
  font-size: 2rem;
  line-height: 1.2;
  margin-bottom: var(--space-sm);
}

.hero p {
  font-size: 1.125rem;
  margin-bottom: var(--space-lg);
  color: rgba(255, 255, 255, 0.8);
}

.button-primary {
  display: inline-block;
  background-color: var(--color-primary);
  color: #ffffff;
  padding: 0.75rem 1.75rem;
  border-radius: 6px;
  text-decoration: none;
  font-weight: 600;
  font-size: 1rem;
  transition: background-color 0.2s ease;
}

.button-primary:hover {
  background-color: var(--color-primary-hover);
  color: #ffffff;
}

@media (min-width: 768px) {
  .hero {
    padding: 5rem var(--page-padding);
  }

  .hero h1 {
    font-size: 3rem;
  }
}

/* =========================================
   Features Section
   ========================================= */
.features {
  padding: var(--space-xl) 0;
  background-color: var(--color-surface);
}

.features h2 {
  font-size: 1.5rem;
  margin-bottom: var(--space-lg);
  text-align: center;
}

/* Cards: single column on mobile */
.card-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.card {
  background-color: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

.card h3 {
  font-size: 1.125rem;
  margin-bottom: var(--space-xs);
  color: var(--color-text);
}

.card p {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* Cards: three-column row on tablet and above */
@media (min-width: 768px) {
  .card-row {
    flex-direction: row;
  }

  .card {
    flex: 1; /* each card takes equal share of space */
  }

  .features h2 {
    font-size: 1.75rem;
  }
}

/* =========================================
   Footer
   ========================================= */
.site-footer {
  background-color: var(--color-text);
  color: rgba(255, 255, 255, 0.7);
  padding: var(--space-lg) 0;
  text-align: center;
  font-size: 0.875rem;
}

Tracing the Responsive Behavior

Trace
What the page looks like at different widths
  • At 375px.main-nav is hidden (display: none). .hero h1 is 2rem. .card-row is a vertical flex column. .container fills 100% of the width with 1.25rem padding on each side.
  • At 640pxThe @media (min-width: 640px) query fires. .main-nav becomes visible and navigation links appear in the header.
  • At 768pxThe @media (min-width: 768px) query fires. .hero gets more padding (5rem). .hero h1 grows to 3rem. .card-row switches from column to row, and the three cards appear side by side.
  • At 1200px+The .container's max-width: 1200px activates. Content stops growing wider, and the site is centered on the page.

Chapter Summary

Key Terms

responsive design
The practice of building websites that detect and adapt to different screen sizes, orientations, and devices.
viewport
The visible area of the browser window. On a phone, the viewport is the phone screen width; on a desktop browser, it is the browser window width.
viewport meta tag
An HTML meta element with name="viewport" that tells mobile browsers to use the device's actual width instead of simulating a desktop viewport.
mobile-first
A design and development approach where base styles are written for narrow screens, and media queries add enhancements for wider screens.
relative unit
A CSS measurement unit whose value depends on another value, such as the parent's font size (em), the root font size (rem), the parent's dimensions (%), or the viewport (vw, vh).
fluid container
A container that uses width: 100% and max-width to fill available space while capping its maximum width.
media query
A CSS rule that applies styles only when a specific condition about the user's environment is true, most commonly a minimum or maximum viewport width.
breakpoint
A specific viewport width value at which a responsive layout changes, used in min-width or max-width conditions inside a media query.
min-width
A media query condition that applies styles when the viewport is at least the specified width. Used in mobile-first responsive CSS.
max-width
A media query condition that applies styles when the viewport is no wider than the specified width. Used in desktop-first responsive CSS, and also a CSS property for capping element widths.
fluid image
An image that scales down on narrow viewports, achieved using max-width: 100%; height: auto.
srcset
An HTML attribute on img that provides multiple image source files for the browser to choose from based on screen density or viewport size.
hamburger menu
A navigation pattern where navigation links are hidden on mobile behind a button, revealed when the button is pressed.
prefers-color-scheme
A media feature that detects the user's system color mode preference (light or dark).
prefers-reduced-motion
A media feature that detects whether the user has requested less motion or animation in their system settings.

Concept Check

Answer these questions before beginning the full review questions. They check basic understanding, not deep analysis.

  1. In your own words, what is responsive design, and what problem does it solve?
  2. What is the difference between mobile-first and desktop-first CSS?
  3. Why does rem respect a user's browser font size preferences while px does not?
  4. What two CSS properties make an image responsive at the most basic level?
  5. What is a breakpoint, and how should you decide where to place one?
  6. What does the viewport meta tag do, and why does responsive CSS fail without it?
  7. What is a hamburger menu, and what problem does it solve?

Common Misconceptions

Misconception 1
"Responsive design just means shrinking everything to fit a smaller screen."
Shrinking a fixed layout proportionally — the way a photocopier shrinks a page — still leaves text too small to read and tap targets too small to press accurately. Responsive design restructures the layout itself: columns stack, navigation collapses, font sizes adjust independently, and images scale within fluid containers. It is a change in structure, not just scale.
Misconception 2
"If my page looks fine in my desktop browser window, it's responsive."
A page can look correct at the one width you happen to be viewing and still break badly at other widths. Responsive design must be verified across a range of viewport sizes — narrow phone widths, tablet widths, and wide desktop widths — using browser developer tools or real devices, not just the width your browser window happens to be open to right now.
Misconception 3
"More breakpoints make a layout more responsive."
Adding many breakpoints targeting every conceivable device size produces a stylesheet that is hard to maintain and often inconsistent. A well-designed fluid layout with relative units and one or two thoughtful breakpoints often handles a wider range of screens more gracefully than a layout with a dozen narrow, device-specific overrides.
Misconception 4
"Mobile-first means designing only for mobile and ignoring desktop."
Mobile-first describes the order in which you write your CSS — narrow-screen styles first, wider-screen enhancements added afterward with min-width media queries — not a decision to neglect desktop users. A mobile-first stylesheet still produces a complete, well-designed desktop experience; it simply builds up to it rather than building down from it.
Misconception 5
"Disabling pinch-to-zoom keeps my carefully designed layout intact."
Setting user-scalable=no on the viewport meta tag does prevent users from zooming, but it does so by removing an accessibility feature that people with low vision rely on. A responsive layout should remain usable and attractive at the intended sizes without needing to strip away the user's ability to zoom.
PracticeCode Reading

Read each code block and answer the questions that follow.

Code Block 1
.hero-image {
  width: 100%;
  max-width: 960px;
  height: auto;
}
  1. What does width: 100% do to this image on a narrow phone screen?
  2. What does max-width: 960px do on a 1400px wide monitor?
  3. Why is height: auto important for this image?
Code Block 2
.description {
  font-size: 1.125rem;
  max-width: 65ch;
  line-height: 1.7;
}

@media (min-width: 900px) {
  .description {
    font-size: 1.25rem;
  }
}
  1. What unit is used for font size, and what is the benefit of using it instead of px?
  2. What does max-width: 65ch limit?
  3. At a viewport of 850px, what font size does .description have? At 950px?
Code Block 3
.grid {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

@media (min-width: 640px) {
  .grid {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .grid > * {
    flex: 1 1 200px;
  }
}

@media (min-width: 1024px) {
  .grid {
    gap: 2.5rem;
  }
}
  1. What does the layout look like at 400px?
  2. What does the layout look like at 700px?
  3. What is the only thing that changes at 1024px?
  4. Is this CSS mobile-first or desktop-first? How do you know?
PracticeCode Tracing

Trace through the following sequence of breakpoints and describe what the page looks like at each width.

.page-title {
  font-size: 1.5rem;
  text-align: center;
}

@media (min-width: 768px) {
  .page-title {
    font-size: 2.5rem;
    text-align: left;
  }
}

@media (min-width: 1200px) {
  .page-title {
    font-size: 3.5rem;
  }
}
Viewport Widthfont-sizetext-align
375px??
768px??
900px??
1200px??
1440px??
PracticePredict the Result

Look at the following HTML and CSS. Predict what the layout looks like at 500px wide and at 900px wide before checking in a browser.

HTML
<div class="panel-group">
  <div class="panel">Alpha</div>
  <div class="panel">Beta</div>
</div>
CSS
.panel-group {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  background-color: #f0f0f0;
}

.panel {
  background-color: #3a5ce7;
  color: white;
  padding: 2rem;
  text-align: center;
  border-radius: 6px;
}

@media (min-width: 768px) {
  .panel-group {
    flex-direction: row;
  }

  .panel {
    flex: 1;
  }
}
PracticeDebugging Practice

Each code sample below has a problem. Identify the problem and explain how to fix it.

Problem 1
<head>
  <title>My Portfolio</title>
  <link rel="stylesheet" href="css/style.css">
</head>

The page looks fine in a desktop browser but is zoomed out and tiny on a real phone, and the mobile media queries are not activating correctly. What is missing and what should be added?

Problem 2
.hero-photo {
  width: 1200px;
  height: auto;
}

On a phone, the hero image is forcing horizontal scrolling. How should this be fixed?

Problem 3
/* Mobile: cards should stack */
.cards {
  display: flex;
  flex-direction: row; /* should be column on mobile */
}

/* Desktop: row */
@media (min-width: 768px) {
  .cards {
    flex-direction: row;
  }
}

What is wrong with this code from a mobile-first perspective, and what is the correct fix?

Problem 4
body {
  font-size: 12px; /* feels like it prevents overflow */
}

h1 {
  font-size: 36px;
}

p {
  font-size: 14px;
}

A student has used px for all font sizes. Identify two problems this creates and rewrite using rem.

PracticeBuild Tasks
  1. Write a CSS container that is 100% of the viewport width minus 2rem of padding on each side, never wider than 1100px, and centered horizontally.
  2. Write a fluid image rule that prevents images from overflowing their containers, maintains the aspect ratio, and prevents the default gap that appears below images in some browsers.
  3. Write a media query that applies only when the viewport is 900px or wider, changes .sidebar from display: none to display: block, and changes .main-content from width: 100% to width: calc(100% - 320px).
  4. A student has a row of four navigation links that overflows at 480px. Rewrite the CSS so that at 480px and below the links stack vertically in a column, at 481px and above the links display in a horizontal row, and the code uses a mobile-first approach.
  5. Write a CSS variable block and responsive container that defines a --page-padding variable set to 1rem by default, a --container-max variable set to 1140px, a .container class using both variables, and that increases --page-padding to 2rem at 1024px and above.
Mini-ProjectResponsive Landing Page
Project Goal
Build a simple responsive landing page that looks good on phones (375px), tablets (768px), and desktops (1200px)
  • HeaderA sticky header with a logo on the left and navigation on the right. Hide the navigation below 640px and show it on wider screens.
  • HeroA hero section with a centered heading, a short paragraph, and a button. Give the hero more padding on desktop than on mobile.
  • FeaturesA features section with three content cards. Stack the cards vertically on mobile, and display them in a horizontal row on tablet and above.
  • FooterA simple footer with copyright text.

Requirements: Use mobile-first media queries with min-width conditions. Use rem units for font sizes and spacing. Use a fluid container with max-width and margin: 0 auto. Include the viewport meta tag. Apply max-width: 100%; height: auto to any images. Use at least two breakpoints. Use CSS custom properties for colors and spacing values.

Testing Checklist Before Submitting
Confirm each item using browser developer tools
  • Opens and looks correct at 375px in browser developer tools.
  • Navigation is hidden at 375px, visible at 768px.
  • Cards stack at 375px, row at 768px.
  • No horizontal scrolling at any width.
  • Text is readable at all sizes without zooming.
  • Hero section has correct spacing at mobile and desktop.
  • max-width container is centered at 1200px and above.
  • Passes the viewport meta tag check in developer tools.
ReviewAccessibility Check

Responsive design and accessibility are closely related. Review your responsive landing page against this checklist.

CheckWhat to Verify
Text sizeAre rem units used for font sizes so text scales with browser font preferences?
Touch targetsAre buttons and links at least 44px tall (using min-height or padding) so they are easy to tap on a phone?
ContrastDoes text color have sufficient contrast against the background at all breakpoints? (4.5:1 is the recommended minimum for normal-sized body text.)
Keyboard navigationCan the navigation be reached and activated using only a keyboard (Tab and Enter)?
Image alt textDo all images have meaningful alt attributes?
Zoom behaviorDoes the viewport meta tag avoid user-scalable=no? Users must always be allowed to zoom.
OrientationDoes the page work in both portrait and landscape? Locking to one orientation can exclude users with a fixed-mounted device.
ReviewMixed Review

These questions combine material from Chapters 11 through 17.

  1. In Chapter 14, you learned about the box model. How does box-sizing: border-box interact with fluid widths? If an element has width: 100% and padding: 0 1.5rem, does the padding reduce the visible content width when box-sizing is border-box? Explain.
  2. In Chapter 15, you used Flexbox for card layouts. In the responsive card example in this chapter, the cards switch from flex-direction: column to flex-direction: row at 768px. What other Flexbox property in the desktop media query ensures each card takes an equal share of the row?
  3. In Chapter 12, you learned about CSS specificity. If a base style and a media query rule target the same element with the same selector, which one wins when the media query condition is true? Explain why.
  4. In Chapter 13, you used colors and typography. Why is rem preferred over px for font-size in a responsive stylesheet?
  5. In Chapter 11, you learned about external stylesheets. A student links two CSS files: a base stylesheet and a responsive stylesheet. Which file should be linked second? Why does order matter?
  6. You have a section that uses CSS Grid with three columns at 1fr 1fr 1fr. On mobile you want a single column. Write the complete CSS for both states using a mobile-first approach.
Chapter 17 Checklist
Use this to confirm your understanding before moving to Chapter 18
Concepts
  • I can explain why responsive design is necessary given the range of modern screen sizes.
  • I can describe typical viewport widths for phones, tablets, laptops, and desktops.
  • I can explain the difference between mobile-first and desktop-first CSS.
  • I can choose appropriate relative units — em, rem, %, vw, vh, ch — for different sizing tasks.
  • I can build a fluid container using width and max-width together.
  • I can apply the fluid image rule and explain layout shift.
  • I can write a media query using min-width and explain other media features.
  • I can choose breakpoints based on content rather than specific devices.
  • I can explain the purpose of the viewport meta tag.
Applications
  • I can build a responsive navigation structure with a hamburger toggle pattern.
  • I can use browser developer tools to test a layout at multiple widths.
  • I can identify and fix horizontal overflow, unreadable text, and other common responsive problems.
  • I can build a small, fully responsive landing page using everything in this chapter.
Study Habits
  • I test my layouts at multiple widths rather than only the width my browser happens to be open to.
  • I resize my browser window slowly and watch for the point where a layout starts to break.
  • I know never to disable zoom with user-scalable=no.
Preview — Chapter 18
CSS Variables, Themes, and Reusable Styles

Chapter 17 taught you how to build layouts that adapt to any screen size using media queries, relative units, fluid containers, and responsive images. You now have the tools to make pages that work on phones, tablets, and desktops. Chapter 18 introduces CSS variables, themes, and reusable styles. You will learn how to define custom properties that store your color palette, spacing scale, and typography values. Instead of repeating the same hex code or pixel value throughout a stylesheet, you define it once and use it everywhere. When you want to update a color, you change one line. When you build a dark mode variant, you simply override a handful of variables. Chapter 18 turns a stylesheet into a design system — organized, maintainable, and built for growth.

MGU Library Connection
  • Web Development: HTML, CSS, and JavaScript — Appendix E: CSS Layout Reference
  • Web Development: HTML, CSS, and JavaScript — Appendix M: Glossary
  • Companion resource: Responsive Design Checklist
  • Companion resource: Media Query Guide
  • Companion resource: Browser Developer Tools Guide
  • Next section: Chapter 18 — CSS Variables, Themes, and Reusable Styles