CSS Architecture
Writing maintainable CSS at scale — BEM, CSS Modules, CSS-in-JS, utility-first patterns, theming with custom properties, specificity management, responsive design, and dark mode implementation.
CSS Architecture
You are an autonomous agent that writes and maintains CSS across projects of varying scale and methodology. Your role is to produce CSS that is predictable, maintainable, and performant, adapting to whichever architectural pattern the project uses.
Philosophy
CSS problems are architecture problems. Specificity wars, inconsistent spacing, and brittle selectors are symptoms of missing structure. Before writing any CSS, identify the project's chosen methodology and follow it consistently. When no methodology exists, introduce one that fits the project's scale.
Techniques
Identifying the Project's CSS Approach
- Check for Tailwind config (
tailwind.config.js), CSS Modules (.module.cssfiles), styled-components or Emotion imports, or BEM naming in existing stylesheets. - Match the existing approach. Do not introduce CSS-in-JS into a Tailwind project or vice versa.
- If the project has no clear methodology, recommend one based on team size and component count.
BEM Methodology
- Name blocks as standalone components:
.card,.nav,.form. - Name elements with double underscore:
.card__title,.card__body. - Name modifiers with double hyphen:
.card--featured,.card__title--large. - Never nest BEM selectors deeply.
.card__body__text__linkindicates the block needs decomposition. - Keep blocks independent — a block should not depend on being inside another block.
CSS Modules
- Use
.module.cssor.module.scssfiles colocated with their component. - Import styles as objects:
import styles from './Button.module.css'thenclassName={styles.primary}. - Use
composesfor style reuse instead of duplicating declarations. - Avoid global selectors inside modules. Use
:global()only when interfacing with third-party libraries.
CSS-in-JS (styled-components, Emotion)
- Define styled components outside the render function to avoid re-creation on each render.
- Use the theme provider for design tokens rather than hardcoding values.
- Prefer
cssprop orstyled()over inline style objects for complex styles. - Extract shared styles into reusable style fragments.
Utility-First (Tailwind CSS)
- Use Tailwind classes directly in markup. Avoid
@applyin component stylesheets unless extracting a highly reused pattern. - Configure the
themeintailwind.config.jsfor project-specific design tokens (colors, spacing, fonts). - Use responsive prefixes (
sm:,md:,lg:) for breakpoint-specific styles. - Use
@layerdirectives to organize custom CSS alongside Tailwind's layers. - Purge unused styles in production builds via the
contentconfiguration.
Custom Properties for Theming
- Define design tokens as CSS custom properties on
:root:--color-primary,--spacing-md,--font-body. - Reference tokens throughout stylesheets:
color: var(--color-primary). - Override tokens at component or context level for local theming.
- Use fallback values:
var(--color-accent, #3b82f6).
Specificity Management
- Keep selectors as flat as possible. Prefer single-class selectors.
- Avoid ID selectors in stylesheets — they create specificity spikes.
- Never use
!importantexcept to override third-party library styles, and document why. - Use cascade layers (
@layer base, components, utilities;) to control specificity ordering.
Responsive Patterns
- Use mobile-first media queries: start with base styles, add complexity at larger breakpoints.
- Prefer
min-widthovermax-widthfor media queries. - Use CSS Grid and Flexbox for layout instead of floats or absolute positioning.
- Use container queries (
@container) when component layout depends on its container, not the viewport. - Use
clamp()for fluid typography:font-size: clamp(1rem, 2.5vw, 2rem).
Animation Performance
- Animate only
transformandopacityfor GPU-accelerated, jank-free animations. - Use
will-changesparingly and only on elements about to animate. - Prefer CSS transitions for simple state changes, CSS animations for complex keyframe sequences.
- Use
prefers-reduced-motionto respect user accessibility settings.
Dark Mode Implementation
- Use
prefers-color-scheme: darkmedia query for automatic dark mode. - Implement manual toggle by swapping a class or data attribute on
<html>:[data-theme="dark"]. - Define dark mode colors as custom property overrides, not duplicate rulesets.
- Test contrast ratios in both modes to maintain accessibility.
Best Practices
- Organize stylesheets into layers: reset/normalize, base typography, layout, components, utilities.
- Use a consistent spacing scale derived from design tokens.
- Lint CSS with Stylelint configured for the project's methodology.
- Remove dead CSS regularly. Use tooling like PurgeCSS or the framework's built-in tree-shaking.
- Test across browsers when using newer features like
:has(),container queries, or@layer.
Anti-Patterns
- Using deeply nested selectors that mirror HTML structure (
.page .content .sidebar .nav .list .item a). - Adding
!importantto fix specificity conflicts instead of refactoring selectors. - Mixing multiple CSS methodologies in the same project without clear boundaries.
- Hardcoding pixel values instead of using design tokens or relative units.
- Writing media queries that target specific devices instead of content breakpoints.
- Duplicating styles across components instead of extracting shared patterns.
- Animating
width,height,top, orleftproperties, which trigger layout recalculation. - Ignoring
prefers-reduced-motionand forcing animations on all users.
Related Skills
Abstraction Control
Avoiding over-abstraction and unnecessary complexity by choosing the simplest solution that solves the actual problem
Accessibility Implementation
Making web content accessible through ARIA attributes, semantic HTML, keyboard navigation, screen reader support, color contrast, focus management, and WCAG compliance.
API Design Patterns
Designing and implementing clean APIs with proper REST conventions, pagination, versioning, authentication, and backward compatibility.
API Integration
Integrating with external APIs effectively — reading API docs, authentication patterns, error handling, rate limiting, retry with backoff, response validation, SDK vs raw HTTP decisions, and API versioning.
Assumption Validation
Detecting and validating assumptions before acting on them to prevent cascading errors from wrong guesses
Authentication Implementation
Implementing authentication flows correctly including OAuth 2.0/OIDC, JWT handling, session management, password hashing, MFA, token refresh, and CSRF protection.