# Exercise: Bike Cards That Fit Anywhere

Make one Spoke & Chain bike card fit three kinds of spots, a wide feature, a catalog column and a narrow sidebar, with named containers, @container rules and a fluid title, and let the tests check each part.

Journeyman · CSS · Updated October 30, 2026

Spoke & Chain's catalog page shows the same bike card in three kinds of spots: a wide "Bike of the month" spot at the top, a catalog of three columns, and a narrow "Staff pick" sidebar. Someone made the cards side by side with a media query, and on a laptop it went wrong: every card went side by side, so the bikes in the narrow catalog columns and the sidebar are crushed into slivers. Your job is to make the card fit whatever space it's given, with container queries, and to give each card's title a size that grows with its card. Tests check each part as you go.

## Before you start

You need Node.js to run the tests. *Setup: VS Code, a Browser and Node.js* installs it, along with VS Code and Live Server. Everything else, the page and its pictures included, comes with the exercise code.

## Get the exercise code

In the **Exercise** box beside the lesson, choose **Get the starter on GitHub** to open its GitHub repository. Click **Code**, then **Download ZIP**, and unzip it into your `css-in-depth` folder.

The folder holds:

- `index.html`: the catalog page, with five bike cards. It's ready, and you don't change it.
- `styles.css`: the colors, the fonts, the page layout and the card's stacked look are ready. Your work goes below the line that says *Yours: cards that fit their space*, and the media query marked *The problem* is yours to delete.
- `images/`: a picture of each bike.
- `page.test.js` and `package.json`: the tests. You don't need to change these.

Open the folder in VS Code, right-click `index.html` and choose **Open with Live Server**. Make the window wide, and look at the sidebar's card.

## What to do

Every card sits in its own spot, a `<div class="card-spot">`, and every card has the same classes:

```html
<div class="card-spot">
  <article class="bike-card">
    <img class="bike-card-photo" src="images/gravel-fox.svg" alt="The Gravel Fox, an orange gravel bike with wide tires and drop handlebars">
    <div class="bike-card-body">
      <h3 class="bike-card-title">Gravel Fox</h3>
      <p class="bike-card-type">Gravel bike</p>
      <p class="bike-card-price">$1,180</p>
      <p class="bike-card-blurb">Paved road to dirt trail and back again: wide tires, a comfortable fit and mounts for three water bottles.</p>
      <a class="bike-card-button" href="#gravel-fox">See the Gravel Fox</a>
    </div>
  </article>
</div>
```

The comment at the top of `styles.css` lists the work, and the README says the same:

1. **Make every spot a container**: each `.card-spot` measures its width, and is named `bike-spot`.
2. **Delete the problem**: the media query that makes every card side by side on a wide screen.
3. **Side by side when there's room**: an `@container bike-spot` rule that gives the card two columns once its spot is wide enough, somewhere from 26rem to 34rem. Look at the page to decide where.
4. **A look for the wide spot**: a second, wider `@container bike-spot` rule, at least 8rem wider and after the first, for the bike of the month. What it changes is up to you.
5. **A fluid title**: `.bike-card-title` gets a font size with `clamp()`, its limits in rem and a preferred size that mixes rem and `cqi`.

Leave the page layout's media queries alone: the sidebar moving beside the main area is about the screen, and a media query is the right tool for that.

## Check your work

In VS Code, open a terminal (**Terminal > New Terminal**). Run `npm install` once, to download what the tests need, then run the tests as often as you like:

```bash
npm install
npm test
```

At first seven of the eight tests fail. That's expected: only the first one passes, because it checks the page that's already there. Each part you add turns its test green. A failing test's message says what it found and what to fix, for example *The rule for .bike-card sits inside @media (min-width: 60rem), so it changes the cards by the screen's width.*

The tests read your rules, but they can't measure a container: the browser they use doesn't lay out pages. The README's **How it should look** checklist covers that part. Go through it in device mode at 375, 768 and 1280 pixels wide.

## Hints

- **Measure the spot, change the card.** A container query styles what's inside the container, never the container itself. *Container Queries: Components That Fit Their Space* shows why each card sits in a wrapper.
- **Where does the card start to look empty?** Make the window narrow, then widen it slowly while you watch the bike of the month. The width of its spot when there's room for a photo beside the words is your first breakpoint. Hover a `.card-spot` in the Elements panel, and the page shows its width.
- **Two rules, both matching?** In a wide spot both of your `@container` rules apply, and the later one wins where they disagree. Small spots first, then more room.
- **A title that grows with its card.** `cqi` is 1% of the container's width, the way `vw` is 1% of the window's. *Fluid Type and Spacing with clamp()* shows how to pick the minimum and the maximum, and why the preferred size keeps a rem.
- **Something changed in the wrong spot?** Inspect the card and look at the Styles pane: it shows each `@container` rule that's applying, above the declarations inside it.

## When you're done

Every test is green, and the end of the test run says:

```text
ℹ tests 8
ℹ pass 8
ℹ fail 0
```

On a phone, every card is stacked. On a tablet, the bike of the month and the staff pick, which now runs the full width below the catalog, sit side by side, while the catalog's narrower cards stay stacked. On a laptop, the bike of the month has its wide-spot look, and the sidebar's card is stacked and readable. One card, one set of rules, and it fits every spot. Now ask yourself: if the shop added a fourth spot tomorrow, say a footer with two cards side by side, how much CSS would you need to add for the cards? If the answer is "none", your container queries are doing their job.

## So what

The card you built is a **component**: a piece of a page that works wherever it's placed. That's how teams build big sites, from shops to streaming services: they design a card, a menu or a player once, and container queries let it fit a sidebar, a grid or a full-width banner without a new rule for every page.

## What Module 5 unlocks

That's Module 4 done: your pages work from a 320-pixel phone to a wide screen, with breakpoints where the content needs them, fluid sizes, pictures that fit and components that adapt to their space. The Module 4 project, *Your Travel Bucket List*, puts all of it into a site about six places you dream of going, with their photos, why each is on the list, the best time to go and what to pack. You'll open it on your own phone to check it.

A page that fits every screen can still look a little off, and it's often hard to say why. Module 5 is design. It shows why some pages look professional and others don't, and the small rules behind the difference: spacing, alignment, a type scale. You'll choose fonts and colors that read well for everyone, with contrast you can measure. You'll theme a whole site, light and dark, from a handful of variables, so changing one color changes it everywhere. And you'll add motion that helps the reader, a button that responds or a card that eases into view, and calms down for people who asked their device for less motion.

## Key terms

- [Container query](https://www.ask-codey.com/glossary/container-query)
- [@container](https://www.ask-codey.com/glossary/container)
- [Container type](https://www.ask-codey.com/glossary/container-type)
- [Container name](https://www.ask-codey.com/glossary/container-name)
- [Container query units](https://www.ask-codey.com/glossary/container-query-units)
- [clamp()](https://www.ask-codey.com/glossary/clamp)

## Related

- [Container Queries: Components That Fit Their Space](https://www.ask-codey.com/lessons/css-container-queries)
- [Fluid Type and Spacing with clamp()](https://www.ask-codey.com/lessons/css-clamp-fluid-type)
- [calc(), min() and max(): Math in CSS](https://www.ask-codey.com/lessons/css-calc-min-max)
- [Media Queries and Breakpoints](https://www.ask-codey.com/lessons/css-media-queries)

Source: https://www.ask-codey.com/lessons/exercise-css-bike-shop-container-cards
