the IT Hustle
ツール実践マニュアル概要
AI CriticismAI活用2026-03-18•12 min で読める

CSS Tricks AI Generates But Can't Explain

著者: Salty Deprecated Software Engineer

✨ AI アシスト コンテンツ

この記事はAIの支援を受けて作成され、正確性と品質についてチームが審査しました。すべての技術情報と例は検証済みです。

I was reviewing a junior developer's pull request last week. The CSS was generated entirely by AI. It worked — sort of. The layout looked right in Chrome on a 1440px screen. But resize the browser? Switch to Firefox? Load it on a phone? Everything fell apart.

AI can write CSS that passes the eye test. But it consistently produces CSS that's fragile, over-specific, and fundamentally misunderstands how the cascade works. The code compiles. The pixels line up. But the engineering behind it is a house of cards.

Here's the thing: CSS looks simple. It's "just styling," right? But CSS is actually one of the hardest languages to write well because it requires understanding visual design, browser rendering, accessibility, responsiveness, and the cascade — simultaneously. AI gets none of that context.

Let's walk through the CSS patterns AI generates confidently but can't actually explain — and what you should do instead.

The z-index Arms Race

Ask AI to fix an element that's hidden behind another, and you'll get this:

What AI generates:

.modal {

  z-index: 99999;

}

This "works" until another developer adds z-index: 999999to their component. Now you have a z-index war. I've seen production codebases with z-index values in the billions. It's absurd.

AI doesn't understand stacking contexts. It doesn't know that a parent with position: relative and z-index: 1 creates a new stacking context, making child z-index values relative to that parent — not the page.

The right approach — a z-index scale:

:root {

  --z-dropdown: 100;

  --z-sticky: 200;

  --z-overlay: 300;

  --z-modal: 400;

  --z-toast: 500;

}

.modal {

  z-index: var(--z-modal);

}

Why this matters:

  • A defined scale prevents arbitrary escalation
  • Every developer knows what values are available
  • You can reason about layer order without reading every stylesheet

Specificity Wars: When AI Fights the Cascade

AI loves !important. It's the nuclear option — it overrides everything. And AI reaches for it constantly because it "fixes" the immediate problem.

What AI generates when styles aren't applying:

.sidebar .nav .link.active {

  color: blue !important;

  background: white !important;

  font-weight: bold !important;

}

This CSS has a specificity score of 0-4-0 (four classes) plus three !important declarations. You now need an even more specific selector or an !important on the override to change anything. The cascade is broken.

The right approach — use cascade layers and minimal specificity:

/* Low specificity, easy to override */

.nav-link {

  color: gray;

}

.nav-link[aria-current="page"] {

  color: blue;

  font-weight: 700;

}

Why this matters:

  • Low specificity means any component can override styles without escalation
  • Using semantic attributes like aria-current adds meaning and accessibility simultaneously
  • No !important means the cascade works as designed

Flexbox vs Grid: AI Picks the Wrong One

AI defaults to Flexbox for almost everything. Even for layouts that are clearly grid-based — card grids, dashboards, form layouts. Why? Because Flexbox appeared in training data more often.

What AI generates for a card grid:

.card-grid {

  display: flex;

  flex-wrap: wrap;

  gap: 16px;

}

.card {

  flex: 0 0 calc(33.333% - 16px);

}

This "works" but it's fragile. The calc() math breaks when you change the gap. The last row might have awkward spacing. And if a card has more content than others, the row heights get uneven.

The right approach — CSS Grid:

.card-grid {

  display: grid;

  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));

  gap: 16px;

}

The rule of thumb:

  • Flexbox = one-dimensional layouts (navbars, button groups, centering content)
  • Grid = two-dimensional layouts (card grids, page layouts, dashboards, form fields)
  • If you're using flex-wrap, you probably want Grid instead

Viewport Units: The Mobile Trap

AI loves 100vhfor full-height sections. On desktop, it's perfect. On mobile, it's a nightmare.

On mobile browsers, 100vh includes the area behind the browser's address bar.This means your "full height" section is actually taller than the visible screen. Users see a scroll bar on what should be a full-screen section.

What AI generates:

.hero {

  height: 100vh;

}

/* The right approach: */

.hero {

  height: 100dvh; /* dynamic viewport height */

}

The viewport unit cheat sheet:

  • vh / vw — the original, uses the "large" viewport (includes browser chrome)
  • dvh / dvw — dynamic viewport, updates as the browser chrome appears/disappears
  • svh / svw — small viewport, always the visible area
  • For hero sections, use dvh. For fixed headers, use svh.

Pseudo-Elements: AI's Copy-Paste Problem

AI generates pseudo-elements (::before and ::after) that look creative but violate accessibility principles. The most common mistake: putting meaningful content in pseudo-elements.

What AI generates:

.price::before {

  content: "$";

}

.status::after {

  content: " (active)";

}

Screen readers may skip pseudo-element content. The dollar sign and status text are invisible to assistive technology. This is real information that belongs in the HTML, not the CSS.

Pseudo-elements are for decorative content — borders, icons, visual flourishes. Never for information a user needs to understand the page.

The Box Model: AI Skips the Fundamentals

AI rarely sets box-sizing: border-box globally. It will generate widths and padding that work by accident in the current layout, but break the moment you add a border or change padding.

What AI generates:

.sidebar {

  width: 300px;

  padding: 20px;

  border: 1px solid #ccc;

}

/* Actual rendered width: 342px (300 + 20*2 + 1*2) */

/* Without border-box, padding and border ADD to width */

The right approach — always set this globally:

*, *::before, *::after {

  box-sizing: border-box;

}

Every CSS reset includes this. Every framework includes this. But AI-generated CSS often assumes it's there without setting it, or generates code that works without it by coincidence. When you add padding later, everything shifts.

Responsive Design: Breakpoint Hacks vs Design Philosophy

This is where AI fails hardest. Ask for "responsive CSS" and you get a pile of media queries with hardcoded pixel breakpoints:

AI's approach — breakpoint whack-a-mole:

@media (max-width: 768px) { .grid { grid-template-columns: 1fr; } }

@media (max-width: 480px) { .title { font-size: 24px; } }

@media (max-width: 375px) { .card { padding: 8px; } }

@media (max-width: 320px) { .sidebar { display: none; } }

Modern responsive design should require almost zero media queries.If you're writing breakpoints for specific devices, you're doing it wrong.

The right approach — intrinsically responsive:

.grid {

  display: grid;

  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));

  gap: clamp(1rem, 3vw, 2rem);

}

.title {

  font-size: clamp(1.5rem, 4vw, 3rem);

}

Why this matters:

  • clamp() handles fluid typography and spacing without breakpoints
  • auto-fit / auto-fill make grids respond to available space, not device width
  • min() prevents elements from overflowing their containers
  • This approach works on every screen size, including ones that don't exist yet

CSS Custom Properties vs Hardcoded Values

AI hardcodes colors, spacing, and font sizes throughout the CSS. When you need to change your primary color, you're doing a find-and-replace across 47 files.

What AI generates:

.btn-primary { background: #3b82f6; }

.link { color: #3b82f6; }

.badge { border: 1px solid #3b82f6; }

.header { box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2); }

The right approach:

:root {

  --color-primary: #3b82f6;

  --color-primary-alpha: rgba(59, 130, 246, 0.2);

  --space-sm: 0.5rem;

  --space-md: 1rem;

  --space-lg: 2rem;

  --radius: 8px;

}

.btn-primary { background: var(--color-primary); }

.link { color: var(--color-primary); }

Custom properties also enable dark mode, theming, and component-level overrides. AI treats each CSS rule as isolated. Good CSS is a design system.

Debugging CSS: The Inspector Is Your Friend

AI can't debug CSS. When something looks wrong, it guesses — adding more properties, increasing specificity, throwing !important at the problem. A human opens DevTools.

Browser DevTools show you exactly why CSS isn't working.The computed styles panel shows the final values. The box model diagram shows exact dimensions. Crossed-out rules show what's being overridden and by what.

Here's the debugging process AI can't replicate:

  • Right-click the element, inspect it
  • Check the "Computed" tab for actual rendered values
  • Look for crossed-out styles — that's what's being overridden
  • Check the box model for unexpected padding/margin
  • Toggle properties on/off to isolate the issue
  • Check if a parent is creating a stacking context or overflow clipping

You can experiment with CSS in our CSS Gradient Generator to build gradients visually and see the code update in real time — no guessing, no AI hallucination.

The Bigger Picture: Why Understanding CSS Matters

AI can generate CSS that looks right. That's the easy part. The hard part is CSS that stays right — across browsers, screen sizes, accessibility tools, content changes, and team members editing the code six months later.

The cascade is a feature, not a bug. Specificity is a tool, not an obstacle. The box model is the foundation everything sits on. If you don't understand these three concepts, no amount of AI-generated CSS will save you.

Use AI to generate a starting point. Then review it with these questions:

  • Is the specificity as low as possible?
  • Are colors, spacing, and fonts using custom properties?
  • Does it use Grid where Grid is appropriate?
  • Are viewport units correct for mobile?
  • Is meaningful content in the HTML, not in pseudo-elements?
  • Can you resize the browser to any width without it breaking?

Want to experiment with CSS visually? Try our CSS Gradient Generator — build complex gradients with a live preview and copy the production-ready CSS code. No AI guessing involved.

IT
Salty Deprecated Software Engineer

The IT Hustleの編集用ペンネームで書いています——ノートPC修理技術者、システム管理者、ストレージエンジニア、ソフトウェアエンジニアとしての25年以上の経験を、今はAIエージェントの運用に注いでいます。すべての記事は公開前に人間が確認します。詳しくは編集方針をご覧ください。

ツール一覧全記事私たちについて

最新情報を受け取る

新しいツール、ブログ記事、アップデートをいち早くお届けします。スパムなし。

独自の反ハルシネーション プロンプトを生成する

AIプロンプトエンジンは独自技術を使い、内蔵の検証・矛盾テスト付きプロンプトを生成します。

無料で3回試す →

会社情報

  • 概要
  • 実践マニュアル
  • AI用語集
  • 筆者について
  • お問い合わせ

プロダクト

  • ツール
  • 料金ウォッチ
  • エージェントオプス
  • コード
  • デザイン
  • システム管理
  • 生産性
  • マーケティング
  • ビジネス

法的情報

  • プライバシーポリシー
  • 利用規約
  • 免責事項
  • 編集方針
  • 訂正について

© 2026 Salty Rantz LLC. 無断複製・転載を禁じます。

テクノロジーの変革を乗り越える人々のために。