Exercise: Organize the Board Game Café's Styles
Sort Meeple's 260-line stylesheet into four cascade layers, nest the rules that belong together and remove every !important, while a check compares every style on the page with the original to prove nothing changed.
Journeyman · CSS · Updated
Meeple is a board game café with over 300 games on the shelf, and its website does its job: a list of games, a form to book a table, a snack menu. The trouble is behind the page. Its stylesheet grew one quick fix at a time, rules for the same part are scattered through the file, and three !importants hold it together. The owner wants to add a page of game nights, and nobody dares to touch the CSS. Your job is to put it in order: four layers, nested rules, no !important, and a page that looks exactly the same as before. Checks tell you when each part is done, and one of them compares every style on the page with the original, so you'll know the moment a move changes something.
This is the work of reorganizing someone else's stylesheet, which is a large part of real CSS work: most of the time, you're improving CSS that already exists.
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. Then open the folder in VS Code.
The folder holds:
index.html: Meeple's home page. Ready to use: don't change it.styles.css: the messy stylesheet. For you to reorganize.images/meeple.svg: the café's logo.page.test.js: the six checks, andchecks/, the part of them that works out which rule wins. You don't need to change these.checks/original-styles.css: a copy of the stylesheet as it starts, which the checks compare against. Don't change it.
What to do
Start by opening the page with Live Server, hovering over the links and buttons, and pressing Tab to see the focus outlines: that's the look you're keeping. Here's how the stylesheet starts:
:root {
--cream: #fdf6ec;
--ink: #2d2a32;
--plum: #5b2a86;
--plum-dark: #3f1d5e;
--teal: #2a9d8f;
--coral: #e76f51;
--mustard: #e9c46a;
}
body {
background-color: var(--cream);
color: var(--ink);
font-family: "Trebuchet MS", Arial, sans-serif;
line-height: 1.5;
}
The --cream lines are the café's colors, given names so the rest of the file can use them with var(--cream). You don't need to change them, only move them. Custom Properties: Variables in CSS, in Module 5, teaches how they work.
- Write the layer order line at the top:
reset,base,components,utilities, in that order. - Move every rule into its layer. The README's sorting rules say which rule goes where: the reset is the three rules that undo the browser's defaults; base is plain elements with no classes; components are the café's parts; utilities are the one-job helpers.
- Nest what belongs together. A part's states (
:hover,:focus-visible), its pieces (the game card's heading, details and badge) and its media queries go inside its rule. Three levels deep at most. - Remove every
!important. The utilities layer wins on its own now. - Keep the page the same. Move declarations as they are, and don't change
index.html.
Check your work
Right-click index.html and choose Open with Live Server to see the page; it reloads every time you save.
Then open a terminal in VS Code (Terminal > New Terminal) and run npm install once. After that, run the checks whenever you like:
npm test
At first, check 6 passes and the other five fail. That's expected: the page looks right already; it's the stylesheet that isn't organized. Checks 1 to 5 turn green as you work, and check 6 must stay green all the way. When it turns red, your last move changed how the page looks, and its message says where, for example <a> "Games": text-decoration was underline, now none (on a phone, with the mouse over it). Run the checks after every few rules you move, so you always know which move it was.
Hints
- Moving a rule into a layer can change who wins. Before, the more specific selector won. Now the later layer wins, whatever the selectors. When check 6 turns red, find every rule that sets the property it names and ask which layer each is in. Cascade Layers with @layer shows the rounds.
- A style that lost after a move may belong somewhere else. A rule with no class that only matters for one part of the site, such as an underline for the menu links on hover, is really part of that component.
- When removing an
!importantchanges something, the two rules fighting are probably in the same layer, so specificity and source order decide again, as in Specificity: Scoring a Selector. Nesting the losing rule where it belongs, with&if it's the same element, often settles it. &:hover, not:hover. Without the&, a nested:hovermeans "a hovered element inside this one". CSS Nesting shows the difference.- Lost?
checks/original-styles.cssis the stylesheet as it started. Copy it back overstyles.cssand go one layer at a time.
When you're done
Every check is green, and npm test prints:
> exercise-css-board-game-cafe-layers@1.0.0 test
> node --test
✔ 1) styles.css starts with the layer order: reset, base, components, utilities (0.5414ms)
✔ 2) every rule is inside one of the four layers (0.1555ms)
✔ 3) each rule is in the right layer (0.3354ms)
✔ 4) related rules are nested, no more than three levels deep (0.3354ms)
✔ 5) no !important is left (0.1006ms)
✔ 6) the page looks exactly as it did before (252.5439ms)
ℹ tests 6
ℹ suites 0
ℹ pass 6
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 869.2455
Your times will differ. Now imagine the owner asks for a "Sold out" label on the snack menu that must always be red. Which layer would it go in, and would it need an !important?
So what
You took a stylesheet nobody wanted to touch and made it one anyone can change: each rule has a drawer, each part's styles sit together, and the cascade is decided by one line at the top. That's what keeps a site's CSS workable as a team and a business grow.
What Module 3 unlocks
So far, every page in this course has run top to bottom, one box under another. Module 3 is layout: putting things side by side, in rows, in grids, and on top of each other, and keeping a header on screen while the page scrolls. With flexbox, grid and positioning, you'll build a game dashboard with stat tiles, a high-score table and badges pinned to cards. It's where pages start to look like the sites you use every day.