BSB Part 4B: Polish and Refine
Apply cascade cleanup, detail selectors, pseudo-elements, and restrained motion to bring the Black Swan Bistro site to a polished finish.
✨ From Working to Finished
After Part 4, the Black Swan Bistro is a working multi-page site. It has shared navigation, reusable components, responsive layouts, and consistent styling. That is real progress.
But working is not the same as finished. The navigation links do not respond to hover. The cards sit flat on the page. Some selectors are more specific than they need to be, which will make future changes harder. Small details — a transition here, a pseudo-element there — are what turn a functional layout into a site that feels considered.
This is a polish pass. It is structured, deliberate, and restrained. You are not redesigning. You are refining.
- What is the difference between a site that works and a site that feels finished?
- Have you ever added hover effects or animations that made a page feel worse instead of better?
- Which small CSS details do you notice on sites you admire?
This project applies the cascade, specificity, selector, pseudo-element, and motion skills from the previous two tutorials to the BSB site you have been building since Part 2.
Learning Objectives
By the end of this lesson, you'll be able to:
- ✓ Audit and simplify CSS specificity across a multi-page site
- ✓ Use pseudo-classes and pseudo-elements to refine interactive and decorative details
- ✓ Add restrained transitions and transforms to interactive components
- ✓ Guard all motion with the prefers-reduced-motion media query
- ✓ Apply Apply a structured polish workflow that can carry forward to future projects
Why This Matters:
Polish is not about adding more CSS. It is about making existing CSS clearer, more intentional, and more responsive to user interaction. This pass teaches a repeatable refinement workflow.
Before You Start:
You should be familiar with:
- Styling Details: Selectors, Pseudo-elements, and Motion Review here
- Cascade, Specificity, and Debugging CSS Review here
- BSB Part 4: Multi-page Site Review here
Tutorial Introduction
This tutorial is a structured polish pass. You will work through the Black Swan Bistro site in four focused passes, each building on the last:
- Cascade cleanup — audit specificity and simplify selectors
- Detail selectors — add hover states, focus styles, and decorative pseudo-elements
- Restrained motion — add transitions and transforms to interactive moments
- Final review — check accessibility, reduced motion, and overall feel
Each pass is short and focused. You are not rewriting the site. You are making targeted improvements that show you understand the tools from the last two tutorials well enough to apply them to a real project.
Keep the scope small: a polish pass is not a redesign. If you find yourself wanting to restructure HTML or rethink the layout, note it for later. This pass is about CSS refinement only.
What Polish Means in CSS
Polish is the difference between a page that works and a page that feels considered. It shows up in small details:
- Links that respond smoothly to hover instead of snapping to a new colour
- Cards that lift slightly when interactive, signalling that they lead somewhere
- Navigation that shows focus states for keyboard users
- Decorative touches with pseudo-elements instead of extra HTML
- A stylesheet that is easy to read and change because specificity is low and selectors are clear
None of these changes are large on their own. Together, they signal care and intention. And the process of adding them teaches restraint — knowing when a detail helps and when it just adds noise.
Pass 1: Cascade Cleanup
Before adding any new CSS, clean up what you have. High specificity and unnecessary selector chains make every future change harder. This pass makes the stylesheet easier to work with.
Audit Specificity
Open DevTools on each page and look for crossed-out styles in the Styles panel. Each crossed-out rule is a specificity conflict. Ask:
- Is the winning selector more specific than it needs to be?
- Are there ID selectors that could be replaced with classes?
- Are there long descendant chains like
.hero .container .section-titlethat could be a single class?
Write down each problem you find. You do not need to fix everything at once — just build a clear picture before changing anything.
Simplify Selectors
For each problem in your audit, rewrite the selector to be as simple as possible while keeping the same visual result. The pattern is usually the same:
- Replace ID selectors with class selectors
- Replace long descendant chains with a single purpose-named class
- Remove
!importantby fixing the specificity conflict underneath
After each change, check the page in the browser. If it looks the same, the simplification worked. If something breaks, you have found a specificity dependency worth understanding.
Pass 2: Detail Selectors
With a cleaner stylesheet, you can now add interactive and decorative detail with confidence that new rules will not fight old ones.
Pseudo-classes for Interaction
Review every interactive element on the site — links, buttons, cards that contain links, and navigation items. Each one should have clear :hover and :focus-visible states.
- Navigation links: a colour or underline shift on hover, plus a visible focus ring
- Buttons: a background or shadow change that signals interactivity
- Cards with links: consider styling the whole card on
:hoverand:focus-within
The key rule: every interactive element should look different in its hovered and focused state. If it looks the same regardless of interaction, the user has no feedback.
Pseudo-elements for Decoration
Pseudo-elements let you add decorative detail without touching the HTML. Use them for:
- Section dividers between content areas
- Subtle accent lines under headings
- Decorative marks next to the active navigation link
Keep pseudo-element decoration modest. One or two well-placed touches improve the feel. Five or six make the page feel noisy.
/* Example: accent line under section titles */
.section-title::after {
content: '';
display: block;
width: 3rem;
height: 2px;
background-color: var(--color-golden-orange);
margin-top: 0.5rem;
}Pass 3: Restrained Motion
Motion draws attention. Used well, it signals that the page is responding to the user. Used carelessly, it makes the page feel slow or distracting.
Transitions on Interactive Elements
Add transitions to the interactive states you created in Pass 2. The rules are simple:
- Only transition the properties you are changing — never use
transition: all - Keep durations between 0.15s and 0.3s for interactive feedback
- Use
easeorease-outfor most hover transitions
/* Navigation link transition */
.site-nav__link {
transition: color 0.2s ease;
}
/* Button transition */
.button {
transition: background-color 0.2s ease, box-shadow 0.2s ease;
}Transforms for Subtle Depth
A small translateY on card hover gives a sense of lift without physically moving content around the page. Pair it with a soft box-shadow change for depth:
.menu-card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.menu-card:hover,
.menu-card:focus-within {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}Restraint matters here. A 2px lift is enough to signal interactivity. More than 4px starts to feel like the card is jumping off the page.
Guarding with prefers-reduced-motion
Every transition and transform you add needs a reduced-motion fallback. Place this at the end of your stylesheet:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}This is not a nice-to-have. It is an accessibility requirement. Users with motion sensitivity, vestibular disorders, or a preference for calm interfaces depend on this media query working correctly.
Test it: in macOS, go to System Settings → Accessibility → Display → Reduce motion. In DevTools, open the Rendering panel and emulate prefers-reduced-motion: reduce. Every transition on the site should effectively disappear.
Pass 4: Final Review
The last pass is a full walkthrough. Open each page and check:
- Consistency: do hover states, focus styles, and card lifts feel the same across all pages?
- Reduced motion: enable the preference and verify all motion stops
- Keyboard navigation: tab through every page and check that focus-visible styles appear on every interactive element
- Specificity: open DevTools one more time and confirm there are no unnecessary overrides left
- Feel: does the site feel considered, or does it feel over-decorated?
If something feels like too much, remove it. The best polish passes end with fewer lines of CSS than you expected, not more.
⏸️ Pause & Check: Do You Understand?
Before moving forward, can you answer these?
- Why should you audit specificity before adding new selectors or transitions?
- When is a transition helpful, and when does it get in the way?
- What does the prefers-reduced-motion media query protect against?
Check Your Answers
- High-specificity selectors make future changes harder because each new rule has to fight the existing ones. Cleaning up specificity first gives you a stable foundation so the motion and detail work you add next stays predictable and easy to maintain.
- A transition is helpful when it gives the user a clear signal that something responded to their action, like a button hover or a card lift. It gets in the way when it slows down navigation, distracts from content, or runs on every property change including layout shifts.
- It protects users who experience motion sensitivity, vestibular disorders, or simply prefer a calmer interface. When this preference is active, your CSS should disable or reduce transitions, transforms, and animations so the site stays comfortable and accessible.
How confident are you with this concept?
😕 Still confused | 🤔 Getting there | 😊 Got it! | 🎉 Could explain it to a friend!
Polish the BSB Homepage
Work through these four steps on the BSB homepage. Each step corresponds to one of the four passes.
Audit one page for specificity problems
Open DevTools on the BSB homepage. Find one element where a style is being overridden. Check the Styles panel to see which selector wins and why.
If the winning selector uses an ID or a long chain like .hero .container .section-title, rewrite it using a single class. Confirm the visual result stays the same.
💡 Need a hint?
Add a hover transition to navigation links
In your shared stylesheet, find the .site-nav__link rule. Add a colour or border-bottom change on hover, with a transition:
.site-nav__link {
transition: color 0.2s ease;
}
.site-nav__link:hover {
color: var(--color-golden-orange);
}Check that the active link still looks distinct from the hover state.
💡 Need a hint?
Add a subtle card lift on hover
Find your .menu-card component rule. Add a transform and box-shadow on hover:
.menu-card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.menu-card:hover,
.menu-card:focus-within {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}The lift should be small — just enough to signal interactivity.
💡 Need a hint?
Wrap motion in a reduced-motion guard
At the end of your stylesheet, add a media query that removes or reduces all transitions and transforms when the user prefers reduced motion:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}Test by enabling "Reduce motion" in your operating system accessibility settings or in DevTools under Rendering.
💡 Need a hint?
You know it is working when:
- ☐ At least one specificity problem is identified and fixed
- ☐ Navigation links have a visible hover transition
- ☐ Menu cards lift subtly on hover with transform and box-shadow
- ☐ A prefers-reduced-motion query disables all transitions and transforms
- ☐ The page looks and feels the same as before, but interactions are smoother
💪 Independent Challenge
Now try this on your own without hints!
Your Task:
Requirements:
- Every interactive element on every page has a visible :hover and :focus-visible state
- At least one pseudo-element adds a decorative detail that improves visual hierarchy
- All transitions use specific properties (not transition: all) and stay under 0.3s
- The prefers-reduced-motion query covers every transition and animation on the site
- Keyboard navigation works on every page with visible focus indicators
Stretch Goals (Optional):
- Add a ::before or ::after accent to the active navigation link that shows only on the current page
- Use :first-child or :last-child to remove border or margin from the first/last card in a grid
- Add a subtle scale transform to buttons on :active so they feel like they press inward
Success Criteria:
| Criteria | You've succeeded if... |
|---|---|
| Specificity cleanup | No unnecessary ID selectors or long descendant chains remain in the shared stylesheet. |
| Interaction states | Every link, button, and interactive card has visually distinct hover and focus states. |
| Motion restraint | Transitions are fast, purposeful, and limited to specific properties. |
| Accessibility | prefers-reduced-motion disables all motion. Focus-visible styles work on every interactive element. |
| Overall feel | The site feels considered and professional without being over-decorated. |
Recap
In this tutorial, you applied a structured polish workflow to the Black Swan Bistro site:
- Cascade cleanup made the stylesheet easier to work with by removing specificity conflicts
- Detail selectors added hover, focus, and decorative refinements
- Restrained motion gave interactive elements smooth, purposeful transitions
- Final review checked accessibility, consistency, and overall feel
This four-pass structure is not specific to the bistro. You can apply it to any project when the layout is working but the experience is not yet polished.
Lesson Complete: What You Learned
Key Takeaways:
- Polish is deliberate refinement, not decoration — every change should solve a real problem or improve a real interaction.
- Cascade cleanup comes first because high-specificity CSS makes every future change harder.
- Pseudo-classes and pseudo-elements add detail without adding HTML clutter.
- Transitions and transforms should be restrained: fast, purposeful, and limited to interactive moments.
- The prefers-reduced-motion query is not optional — it is an accessibility requirement for any site with motion.
- A Polish Pass is something you can repeat with every project: audit, detail, motion, review.
Learning Objectives Review:
Look back at what you set out to learn. Can you now:
- ✅ Audit and simplify CSS specificity across a multi-page site Check!
- ✅ Use pseudo-classes and pseudo-elements to refine interactive and decorative details Got it!
- ✅ Add restrained transitions and transforms to interactive components Can explain it!
- ✅ Guard all motion with the prefers-reduced-motion media query Could teach this!
- ✅ Apply a structured polish workflow that can carry forward to future projects Check!
If you can confidently answer "yes" to most of these, you're ready to move on!
Think & Reflect:
Cascade Thinking
- Which specificity problem was the most surprising when you audited your stylesheet?
- How did simplifying selectors change how easy it was to add the hover and motion work?
Detail and Motion
- Which transition or pseudo-element made the biggest difference for the smallest amount of CSS?
- Where did you decide not to add motion, and why?
Looking Ahead
- How would you apply this same four-pass polish workflow to a different project?
- What parts of the BSB site would benefit from JavaScript interaction that CSS alone cannot provide?
Recommended Next Steps
Continue Learning
Ready to move forward? Continue with the next tutorial in this series:
Black Swan Bistro — Part 5 (Prepare for Deployment)Related Topics
Explore these related tutorials to expand your knowledge: