Responsive Design & Accessibility

This guide covers what you need for Build 2: flexbox layout, relative units, media queries, and core accessibility practices. For deeper dives, visit the Resources page.


Flexbox

Flexbox is a CSS layout system that arranges elements in a row or column, with control over alignment, spacing, and wrapping. You apply flexbox rules to the container (the parent element) — the children respond automatically.

The basics

.container {
  display: flex;            /* turns on flexbox */
  flex-direction: row;      /* row (default) or column */
  justify-content: center;  /* alignment along the main axis */
  align-items: center;      /* alignment along the cross axis */
  gap: 1rem;                /* space between items */
  flex-wrap: wrap;          /* allow items to wrap to a new line */
}

justify-content common values: flex-start, flex-end, center, space-between, space-around

align-items common values: flex-start, flex-end, center, stretch

Building a card layout

HTML structure for a "Further Reading" section:

<section class="further-reading">
  <h2>Further Reading</h2>
  <div class="cards">
    <a href="https://example.com" class="card">
      <h3>Article Title</h3>
      <p>Brief description of what this link is about.</p>
    </a>
    <a href="https://example.com" class="card">
      <h3>Article Title</h3>
      <p>Brief description of what this link is about.</p>
    </a>
    <a href="https://example.com" class="card">
      <h3>Article Title</h3>
      <p>Brief description of what this link is about.</p>
    </a>
  </div>
</section>

CSS to make the cards flexible:

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.card {
  flex: 0 1 250px; /* don't grow, shrink if needed, minimum width before wrapping */
  padding: 1.5rem;
  border: 1px solid #ddd;
  border-radius: 0.5rem;
  text-decoration: none;
}

flex: 0 1 250px means: don't grow beyond natural size, shrink if needed, and don't go below 250px wide. Combined with flex-wrap: wrap, the cards automatically stack on narrow screens — no media query needed.


Relative Units

Use relative units instead of fixed pixels (px) so your layout scales with the user's screen size and font preferences.

Unit Relative to Best for
rem Root font size (typically 16px) Font sizes, consistent spacing
em Parent element's font size Component-level padding and margins
% Parent element's width Widths, fluid layouts
vw Viewport width Full-width sections
vh Viewport height Full-height sections

Replace px with rem for font sizes and most spacing. Use % for widths. Keep px for borders and small decorative values where exact size matters.

/* Instead of this: */
h1 { font-size: 32px; }
p  { margin-bottom: 16px; }
main { max-width: 800px; }

/* Use this: */
h1 { font-size: 2rem; }
p  { margin-bottom: 1rem; }
main { max-width: 50rem; }

Media Queries

Media queries apply different styles at different screen sizes. Your page may not need many — flexbox and relative units handle most responsive behavior automatically. Use media queries where your layout genuinely needs adjustment at a specific breakpoint.

Syntax

/* Applies when the viewport is at least 768px wide */
@media (min-width: 768px) {
  /* styles go here */
}

Use min-width (mobile-first): write your default styles for mobile, then add adjustments for larger screens.

Example: responsive image

/* Default (mobile): full width */
.hero-image {
  width: 100%;
  height: auto;
}

/* Larger screens: limit the size */
@media (min-width: 768px) {
  .hero-image {
    max-width: 600px;
  }
}

Accessibility

Accessible design means your page works for everyone — including people using keyboard navigation, screen readers, or who need sufficient color contrast.

Color contrast

Text must have enough contrast against its background to be readable. Use the WebAIM Contrast Checker to test your color combinations. Aim for a AA pass — a contrast ratio of 4.5:1 or higher for normal text.

Alt text

Every image needs a descriptive alt attribute. Be specific about what's in the image.

<!-- Not helpful: -->
<img src="photo.jpg" alt="image">

<!-- Descriptive: -->
<img src="coral-reef.jpg" alt="A colorful coral reef with tropical fish swimming nearby">

<!-- Decorative image with no meaningful content: -->
<img src="divider.svg" alt="">

Keyboard navigation

Your page should be fully usable with just the Tab key. Links and buttons are focusable by default — don't break this. And don't remove the focus outline without replacing it:

/* Don't do this: */
a:focus { outline: none; }

/* Do this instead — style it intentionally: */
a:focus {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}

To test: open your page, press Tab, and navigate through every link and interactive element. Does the order make sense? Is it clear where you are on the page?

Testing with VoiceOver

VoiceOver is the built-in screen reader on Mac.

  1. Turn on/off: Command + F5
  2. Read next item: Control + Option + Right Arrow
  3. Navigate links: Tab
  4. Stop reading: Control

Listen for: Does the page make sense when read aloud? Are images described? Are links clearly labeled (not just "click here")?