This mini project takes a deliberately messy CSS file – duplicated colours, repeated declarations, deep selectors – and refactors it into structured SCSS without changing how the page looks.
The brief
You are handed legacy CSS from a small marketing page. It works visually. It fails maintainability: same hex values twelve times, media queries scattered, button styles copied with tiny tweaks. Your job: same rendered page, better source.
Sample messy CSS (excerpt)
.header { background: #2563eb; color: #fff; padding: 16px 24px; }
.header a { color: #fff; text-decoration: none; }
.header a:hover { text-decoration: underline; }
.btn { display: inline-block; padding: 12px 20px; border-radius: 6px; }
.btn-primary { background: #2563eb; color: #fff; border: none; }
.btn-secondary { background: #fff; color: #2563eb; border: 2px solid #2563eb; }
.card { border: 1px solid #d9d9d9; padding: 24px; margin-bottom: 16px; }
.card h2 { color: #1a1a1a; font-size: 24px; margin-bottom: 8px; }
.card p { color: #5c5c5c; line-height: 1.5; }
@media (min-width: 768px) {
.header { padding: 24px 32px; }
.card { padding: 32px; }
}
Refactor steps
- 1. Inventory – list repeated values (colours, spacing, breakpoints). Those become tokens.
- 2. Create structure – abstracts, layout, components partials; one
main.scssentry. - 3. Extract tokens – replace hex with variables; centralise breakpoints.
- 4. Componentise –
.header,.btn,.cardeach get a partial. - 5. Unify patterns – one button base + modifiers instead of unrelated classes.
- 6. Responsive mixin – replace raw media queries with
bp-up('md'). - 7. Diff the output – compile and compare visual result in the browser side by side if needed.
Target SCSS shape
// abstracts/_variables.scss - extracted tokens
$color-brand: #2563eb;
$color-text: #1a1a1a;
$color-text-muted: #5c5c5c;
$color-border: #d9d9d9;
$color-white: #ffffff;
// components/_button.scss
.button {
display: inline-block;
padding: $space-sm $space-lg;
border-radius: $radius-md;
border: 2px solid transparent;
&--primary {
background: $color-brand;
color: $color-white;
}
&--secondary {
background: $color-white;
color: $color-brand;
border-color: $color-brand;
}
}
Do not change behaviour yet
First pass is a straight refactor – no redesign, no new BEM names in the HTML unless you control the markup. If class names must stay for CMS templates, keep them and clean the SCSS behind them.
Second pass (optional) can rename classes and update HTML together.
Verification
- Screenshot or visual compare before and after.
- Compiled CSS size similar (may shrink slightly after deduplication).
- No new lint errors.
- Token file is the only place brand hex appears.
What you should have learned
Real projects rarely start greenfield. SCSS pays off when you can extract tokens, split files, and compile reliably without breaking the live look. That is the job – not clever syntax for its own sake.
If you worked through these tutorials in order, you now have folder discipline, tokens, tooling, and two projects under your belt. The advanced tutorials goes further on multi-brand systems, PostCSS pipelines, and when to lean on native CSS instead.

