CSS Code Review Checklist
Last updated:
CSS review is architecture review — specificity, tokens, and naming decide whether the next change is calm or chaotic.
01 — Purpose
Review the system, not just the pixels
A CSS diff that only looks pretty in one browser is not a finished review.
Use this checklist on stylesheet changes — new components, overrides, and token updates. It reflects CSS standardsand LSCSS conventions used on this site. Pair with the HTML and JavaScript checklists when behaviour and structure change together.
02 — Architecture
Architecture and layers
Put styles in the layer and folder that match their job — not wherever the file was open.
- new rules live in the right layer — legacy, settings, base, layout, components, utilities, theme, or hacks
- component styles scoped to components — not page-specific soup in global files
- legacy layer used for vendor or third-party CSS — not mixed into components
- hacks folder used honestly — temporary fixes named and ticketed, not permanent architecture
- platform-forced CSS ordering stays in the owning component layer with a documented fallback, support gate, and rule order — not hidden as a hack
- no duplicate component definitions — extend or compose instead of fork
- imports and layer order respected — no unlayered CSS
03 — Cascade
Specificity and selectors
If overriding needs detective work, the selector design failed.
- specificity stays low — no IDs in selectors, no deep nesting chains
- child selectors scoped through the parent — e.g.
.content-card > .title !importantonly used for narrow, documented exceptions such as reduced-motion safety rules or unavoidable vendor overrides- no BEM-style
__elementblocks — two-word components and parent-scoped children instead - overrides explain why they exist — not silent wars between two components
04 — Naming
Naming and state
Name intent and role — not this week’s margin and hex code.
- component classes use two words where possible —
.site-header, not.header - variants use
--— e.g..action-button--primary - state uses generic classes —
.is_active,.is_hidden,.has_error - screen-reader-only text uses
.vh— not.is_hidden, which removes content from the accessibility tree - names describe purpose, not appearance —
.red-text-box-left-smallis a warning sign - JavaScript toggles classes — not inline styles scattered for state
05 — Tokens
Tokens, units, and layout
Hard-coded magic numbers today are tomorrow’s inconsistent redesign.
- spacing, colour, type, radii, and z-index use shared custom properties where values repeat
rem, logical properties, andclamp()preferred over brittle pixel-only layouts- Grid for two-dimensional layout; Flexbox for one-dimensional distribution — choice matches the problem
- typography readable at default and zoomed sizes — line length and line-height considered
- new CSS weight justified — unused rules and duplicate utilities removed
06 — Quality
Motion, focus, and visual quality
Accessibility is part of styling — not a separate ticket.
- focus styles visible and not removed —
:focus-visibleused thoughtfully - colour contrast meets expectations for text and interactive controls
- touch targets and spacing workable on small screens
prefers-reduced-motionrespected — no essential information in animation alone- layout stable where possible — reserved space for async content to reduce shift
07 — Sign-off
Before you approve
Would another developer understand and safely change this CSS in six months?
- change tested at more than one viewport — not only the author’s laptop
- dark mode or theme variants updated if the project uses them
- print or high-contrast edge cases considered when the page is public-facing
- performance review checklist considered if the change adds significant CSS or blocking assets
For platform-forced cases such as @starting-style, transition-behavior, ::details-content, and ::picker(select), use the LSCSS audit checklist as the review reference.