How to Stop Claude Code from Vomiting Arbitrary Styles in Tailwind Projects

Computing/Software9 min read

TuBrief Editorial Written with AI assistance from the source video. The video is the authority. Source video: 3 Ways To Fix Claude Code's #1 Web Design Problem · Chase AI

When writing frontend code with Claude Code, frustrating moments are bound to happen. Just when it seems to be writing code smoothly on its own, it suddenly spits out a generic, overdone UI featuring Inter font and purple gradients. It ignores designated design tokens and directly embeds hardcoded Hex codes like bg-[#1e293b] right into the components.

This isn't because Claude Code is dumb. It happens because it failed to read the context properly when the session started, or because it got lost and couldn't find its footing between Tailwind CSS v3 and v4. Here are three practical configuration strategies to force this terminal-based agent to strictly follow your project's styling rules.


Why It Ignores Design Tokens and Writes Code Whichever Way It Wants

When a session opens, Claude Code reads CLAUDE.md located in the project root. However, if you instruct it midway through a session to edit just a single newly created component, it loses its link to the overall design token file. As context thins out, the agent defaults to the average of its training data—which means falling back to that "generic purple website you've seen a million times before" style.

Structural changes introduced with Tailwind v4 also play a major role. Version 3 defined tokens as JavaScript objects inside theme.extend within the tailwind.config.js file. In contrast, Tailwind v4 (Oxide engine) dropped the JS configuration file and handles CSS variables via @theme directives directly inside the main CSS file. When Claude Code expects the old way and fails to find tailwind.config.js, it immediately starts injecting hardcoded values into JSX.

`css
/* src/styles/globals.css - Tailwind CSS v4 Main Stylesheet */
@import "tailwindcss";

@theme {
--color-brand-primary: oklch(0.55 0.22 260);
--color-brand-secondary: oklch(0.75 0.18 150);
--color-surface-card: oklch(0.98 0.01 240);

--font-display: "Fraunces", serif;
--font-body: "Bricolage Grotesque", sans-serif;

--spacing-section: 5rem;
--radius-card: 0.75rem;
}

`

In a v4 project, you must explicitly specify CSS property names in the --color-* and --font-* format inside your stylesheet. Only then will Claude Code convert them into Tailwind utility classes. If you modify CSS variables mid-task, you should type /compact in the terminal or reopen the session to clear the prompt cache.


How to Write CLAUDE.md to Block Generic UI Outputs

Vague requests like "make it look pretty" are entirely unhelpful. You need to explicitly lay out Negative Constraints—rules on what it must NEVER do—inside CLAUDE.md. If the file gets too long, the AI will miss crucial instructions, so keep design system rules concise and trimmed down to around 20 lines.

`markdown

Frontend Aesthetics & Design System Rules

Typography Discipline

  • ABSOLUTELY FORBIDDEN: Inter, Roboto, Open Sans, Arial, system-ui default fonts.
  • Display Font: Use var(--font-display) / font-display class only.
  • Body Font: Use var(--font-body) / font-body class only.

Color & Token Rules

  • ALL colors MUST reference design tokens in src/styles/globals.css.
  • ABSOLUTELY FORBIDDEN: Hardcoded Hex (#1a202c), RGB, or HSL values in JSX/TSX.
  • ABSOLUTELY FORBIDDEN: Inline style={{ ... }} attributes for layout or color.
  • ABSOLUTELY FORBIDDEN: Generic purple-to-blue gradients on white backgrounds.

Component Directives

  • Always reuse primitives from @/components/ui (shadcn/ui registry).
  • NEVER hand-roll a new Button, Dialog, or Card if it exists in the registry.

`

Connecting external tools alongside writing instruction files makes your rules even more robust:

  1. Install the official frontend design plugin:
    claude plugin install frontend-design@claude-plugins-official
  2. Extract OKLCH colors and spatial systems from reference sites and save them as documentation:
    npx design.md [https://your-brand-reference.com](https://your-brand-reference.com)
  3. Register the shadcn/ui MCP server in .mcp.json so it can query component lists directly:

`json
{
"mcpServers": {
"shadcn": {
"command": "npx",
"args": ["-y", "@shadcn/mcp-server"]
}
}
}

`

With this setup, instead of pulling styles out of thin air, Claude Code will first dig through DESIGN.md and the MCP registry. This cuts down on the time human developers waste fixing messy, tangled layouts.


Verification Scripts to Automatically Catch Style Violations

Prompts alone cannot completely prevent arbitrary values like w-[317px] or inline styles from slipping through during complex tasks. You should bundle Oxlint—a Rust-based linter—with Git Hooks so the agent automatically fixes faulty code whenever it's introduced.

`json
/* .oxlintrc.json */
{
"jsPlugins": ["oxlint-tailwindcss"],
"settings": {
"tailwindcss": {
"entryPoint": "src/styles/globals.css"
}
},
"rules": {
"tailwindcss/no-hardcoded-colors": "error",
"tailwindcss/no-arbitrary-value": "error",
"tailwindcss/prefer-theme-tokens": "error"
}
}

`

Once Oxlint is configured, execute a shell script right before committing to filter out inline styles and Hex codes inside JSX.

`bash
#!/usr/bin/env bash
set -e

echo "Starting UI integrity and inline style check..."

INLINE_STYLES=(git diff --cached -G'style={{' --name-only '*.tsx' '*.jsx' || true) if [ -n "INLINE_STYLES" ]; then
echo "ERROR: Forbidden inline style attributes detected in the following files:"
echo "$INLINE_STYLES"
exit 1
fi

HARDCODED_HEX=(git diff --cached -G'#[0-9a-fA-F]{3,6}' --name-only '*.tsx' '*.jsx' | grep -v 'globals.css' || true) if [ -n "HARDCODED_HEX" ]; then
echo "ERROR: Hardcoded Hex color codes detected in the following files:"
echo "$HARDCODED_HEX"
exit 1
fi

echo "UI integrity check passed."

`

`json
/* .lintstagedrc.json /
{
"
.{jsx,tsx,ts,js}": [
"oxlint --config .oxlintrc.json",
"bash scripts/verify-ui-integrity.sh"
]
}

`

If the check throws an error (Exit Code 1), Claude Code recognizes this log as an error. It then immediately inspects the code and autonomously replaces the Hex values with CSS variable tokens.


Isolating Legacy CSS from Claude Code-Generated Components

Introducing Claude Code into a project with a massive existing stylesheet will lead to class name collisions and broken UI displays. You need to cleanly separate domains using Tailwind v4's prefix() directive and CSS Cascade Layers (@layer).

`css
/* src/styles/globals.css */
@layer legacy, tailwind, overrides;

@layer legacy {
@import "./legacy/old-style.css";
}

@layer tailwind {
@import "tailwindcss" prefix(tw);
}

`

By appending prefix(tw), newly generated classes will have fixed prefixes like tw:bg-brand-primary or tw:flex. This eliminates name overlapping with existing legacy classes like .btn or .card.

Directory structures should also be reorganized to restrict the areas Claude Code can touch:

  1. Move existing legacy code into the src/legacy/ folder and mark it as a no-edit zone.
  2. Collect new components created by Claude Code inside src/design-system/components/.
  3. Add access restriction rules to CLAUDE.md.

`markdown

Directory Rules

  • NEVER edit files inside src/legacy/.
  • All NEW frontend components MUST be placed inside src/design-system/components/.
  • When creating components, import CSS tokens ONLY from @/design-system/tokens/tokens.css.

`


Key Summary by Step

Step Action Item Key Files & Commands Expected Benefit
1. Token Declaration Define CSS variables based on Tailwind v4 @theme src/styles/globals.css Establish a shared standard token baseline for AI and developers
2. Context Setup Configure CLAUDE.md constraints and install official skills claude plugin install frontend-design@claude-plugins-official Prevent overuse of default fonts and unassigned gradients
3. Static Verification Set up Oxlint validation and Husky Hook npx oxlint --config .oxlintrc.json AI self-corrects code when hardcoded styles are detected
4. Style Isolation Apply Tailwind v4 prefix() and @layer @import "tailwindcss" prefix(tw); Prevent class name collisions with existing legacy CSS

The quality of AI-generated code depends less on the prompt sent out and more on the robustness of the verification pipeline catching it back. By drawing clear boundaries in CLAUDE.md and bouncing off hardcoding with Oxlint-based verification scripts, you can reclaim the time previously wasted tweaking styles manually.

Related Video

3 Ways To Fix Claude Code's #1 Web Design Problem

Chase AI23:00

More from the community

Comments

Log in to leave a comment.

No comments yet.