Skip to main content

At most one CSS approach dominates

ab-000223 · ai-slop-code-drift.ui-stack-drift.dual-css-approach
Severity: mediumactive

Why it matters

When no single CSS approach covers at least 70 percent of styled files, every contributor must learn Tailwind utility conventions, CSS Module naming rules, and styled-components template syntax to navigate the codebase. Design tokens live in three places, dark mode implementations diverge, and specificity conflicts between global CSS and scoped modules cause cascade bugs that only appear in production builds after PurgeCSS runs.

Severity rationale

Medium because the risk is developer velocity and visual inconsistency rather than functional bugs, though cascade conflicts can break UI at build time.

Remediation

Designate one approach as primary in CONTRIBUTING.md and rewrite outliers. Tailwind for 70 percent or more of files is the common answer; permit CSS Modules only for genuinely complex one-off components.

// src/components/Card.tsx — primary Tailwind pattern
<div className="rounded-lg border p-4 shadow-sm">

// src/components/ComplexAnimation.tsx — exception via CSS Module
import styles from './ComplexAnimation.module.css'

Add a lint rule or CI check that fails new PRs introducing a fourth approach.

Detection

  • ID: ai-slop-code-drift.ui-stack-drift.dual-css-approach

  • Severity: medium

  • What to look for: Count all styled source files using each of these 4 CSS approaches: (a) Tailwind utility classes (presence of className="..." strings containing utility-shaped tokens like flex, text-, bg-, p-, m-, with 3+ utilities per className), (b) CSS Modules (*.module.css imports), (c) styled-components / emotion (styled.div, css\...`, import styled from 'styled-components'), (d) plain CSS imports (import './foo.css'without.module.`). Count all files using each approach (a file may use more than one). For each approach, compute the percentage of styled files that use it. The dominant approach must account for at least 70% of styled files.

  • Pass criteria: Exactly 1 CSS approach accounts for at least 70% of styled source files. Report even on pass: "Dominant CSS approach: [name] ([X]% of [Y] styled files). Other approaches: [list with percentages]."

  • Fail criteria: No single CSS approach accounts for 70% or more of styled files (split across two or more approaches).

  • Skip (N/A) when: Fewer than 5 styled source files exist in the project (sample too small to assess).

  • Detail on fail: "No dominant CSS approach: Tailwind 45% (18 files), CSS Modules 35% (14 files), styled-components 20% (8 files). Pick one as the primary."

  • Remediation: Mixed CSS approaches mean every component developer has to learn three styling patterns. Pick one as primary and isolate others to specific cases:

    // Good pattern: Tailwind for layout, CSS Modules for one-off complex components
    // Bad pattern: random mixing across the codebase
    
    // src/components/Card.tsx — Tailwind
    <div className="rounded-lg border p-4 shadow-sm">
    
    // src/components/ComplexAnimation.tsx — CSS Module (one-off)
    import styles from './ComplexAnimation.module.css'
    

    Document the rule in CONTRIBUTING.md so future contributors don't add a fourth approach.

Taxons

History