一键导入
css-best-practices
CSS quality patterns: naming, specificity architecture, dark mode, and layout. Trigger: When reviewing CSS quality or stylesheet architecture.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
CSS quality patterns: naming, specificity architecture, dark mode, and layout. Trigger: When reviewing CSS quality or stylesheet architecture.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Paste-ready session summary for context transfer to a new chat. Trigger: User says 'context handoff', 'start fresh', or session needs to continue.
One-at-a-time questioning to fully profile a goal before acting. Trigger: User says 'grill me', goal is vague, or clarification is needed first.
Batch execution with checkpoints. Trigger: When executing plans with batched tasks.
Universal coding principles: DRY, security by default, null guards, and YAGNI. Trigger: When writing or reviewing code in any language or technology.
Accessibility guide (WCAG 2.1/2.2, Level A–AAA). Trigger: When building UI components, interactive elements, or auditing accessibility compliance.
Astro quality patterns: island philosophy, SEO by page type, and Core Web Vitals. Trigger: When reviewing Astro site quality or hydration decisions.
| name | css-best-practices |
| description | CSS quality patterns: naming, specificity architecture, dark mode, and layout. Trigger: When reviewing CSS quality or stylesheet architecture. |
| license | Apache 2.0 |
| metadata | {"version":"1.0","type":"domain"} |
Quality patterns for CSS architecture, specificity management, theming, and layout. Applies to plain CSS, SCSS, and CSS Modules.
Don't use for:
Define semantic tokens, not raw values. One change point, consistent everywhere.
/* ❌ WRONG — raw value duplicated in 40+ places */
.button { background: #3b82f6; }
.link { color: #3b82f6; }
/* ✅ CORRECT — semantic token defined once */
:root { --color-brand-primary: #3b82f6; }
.button { background: var(--color-brand-primary); }
.link { color: var(--color-brand-primary); }
Single class selectors maximum. Avoid ID selectors and !important. If you need !important, the architecture is broken.
/* ❌ WRONG — specificity escalation */
#sidebar .nav > ul li a.active { color: red; }
/* ✅ CORRECT — single class */
.nav-link--active { color: var(--color-brand-primary); }
Use @layer to establish explicit cascade order: reset → base → components → utilities.
/* ✅ CORRECT — predictable cascade, no order-dependency */
@layer reset, base, components, utilities;
@layer reset { *, *::before, *::after { box-sizing: border-box; } }
@layer components { .card { padding: var(--spacing-md); } }
@layer utilities { .mt-4 { margin-top: 1rem; } }
Override custom properties at the theme level. Never duplicate color values per-component.
/* ❌ WRONG — color duplication per component */
@media (prefers-color-scheme: dark) {
.card { background: #1a1a1a; }
.nav { background: #1a1a1a; }
}
/* ✅ CORRECT — one override point for all components */
@media (prefers-color-scheme: dark) {
:root { --color-surface: #1a1a1a; }
}
[data-theme="dark"] { --color-surface: #1a1a1a; }
Grid for 2D layout, Flexbox for 1D alignment. No floats, no percentage hacks.
/* ❌ WRONG — fragile percentage grid */
.col { float: left; width: 33.33%; }
/* ✅ CORRECT — intrinsic grid */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
Unexplained values become unmaintainable. Extract to custom properties with naming that communicates intent.
/* ❌ WRONG — where did 23px come from? */
.modal { margin-top: 23px; }
/* ✅ CORRECT — documented offset */
/* 24px base - 1px border = 23px visual alignment */
.modal { margin-top: calc(var(--spacing-lg) - 1px); }
BEM and utility classes in the same component scope cause naming chaos. Pick one per scope.
<!-- ❌ WRONG — BEM + Tailwind + arbitrary classes -->
<div class="card card--featured mt-4 text-blue-600 card__title">
<!-- ✅ CORRECT — consistent convention per component -->
<div class="card card--featured"> <!-- BEM scope -->
<div class="mt-4 text-blue-600 font-bold"> <!-- Utility scope -->
| Symptom | Cause | Fix |
|---|---|---|
Style needs !important to apply | Specificity war | Flatten with single-class selectors + @layer |
| Dark mode colors duplicated across components | Class-based overrides | Custom properties + media/data-theme override |
| "Why is this 23px?" | Magic number | Extract to custom property with comment |
| Cascade breaks when file order changes | No explicit layer ordering | Add @layer declaration |
| BEM + utility classes mixed in same element | Inconsistent convention | Pick one pattern per component scope |
| Colors wrong in one theme but not another | Raw values, not tokens | Replace with semantic custom properties |
Defining a color, spacing, or size used in 2+ places?
→ Custom property (design token) — not a raw value
Style not applying?
→ Check specificity — is a higher-specificity rule winning?
→ Use browser DevTools to inspect computed styles
→ Fix by lowering specificity of the winning rule, not raising the losing one
Need dark mode?
→ Override custom properties in @media (prefers-color-scheme: dark)
→ Also add [data-theme="dark"] selector for JS-controlled toggle
2D layout (rows AND columns)?
→ CSS Grid
1D layout (row OR column)?
→ Flexbox
Number with no obvious origin?
→ Magic number — extract to custom property or document with comment
BEM or utility classes?
→ New component in isolation → BEM (scoped, semantic)
→ Rapid composition of existing design tokens → utility
→ Never mix in same element's class list
File order matters for correct rendering?
→ Add @layer to make cascade order explicit and file-order-independent
/* Design tokens */
:root {
--color-surface: #ffffff;
--color-text: #111827;
--color-brand: #3b82f6;
--spacing-md: 1rem;
--radius-card: 0.5rem;
}
/* Dark mode: single override point */
@media (prefers-color-scheme: dark) {
:root {
--color-surface: #1f2937;
--color-text: #f9fafb;
}
}
[data-theme="dark"] {
--color-surface: #1f2937;
--color-text: #f9fafb;
}
/* Component uses tokens — works in both themes automatically */
.card {
background: var(--color-surface);
color: var(--color-text);
padding: var(--spacing-md);
border-radius: var(--radius-card);
}
/* Responsive grid using modern primitive */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: var(--spacing-md);
}
Legacy browser support: Use @supports (--foo: bar) for feature detection rather than static compilation. For environments without custom property support, define fallback values inline before the var() call: color: #3b82f6; color: var(--color-brand-primary);
CSS Modules and custom properties: Custom properties defined in :root are global even in CSS Modules — tokens still work. Component-scoped variables must be defined on the component's root element.
SCSS variables vs custom properties: SCSS variables are compile-time (no runtime theming); custom properties are runtime (theme switching works). Prefer custom properties for any value that changes with theme, viewport, or user preference.
Specificity in third-party overrides: When overriding a third-party library with high specificity, use @layer to wrap the library styles — then your layer-less styles automatically win without !important.