算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
frontend-css-strategy【设计与创意】Use this skill when the user says 'CSS strategy', 'CSS Modules', 'CSS-in-JS', 'utility-first CSS', 'Tailwind CSS', 'styled-components', 'Emotion', 'CSS organization', 'CSS architecture', 'CSS approach', 'BEM', 'CSS naming convention', 'CSS preprocessor', 'Sass', 'PostCSS', 'styled-jsx', 'Linaria', 'vanilla-extract', 'CSS decision', 'styling approach'…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Choose and implement the right CSS approach for the project. Utility-first for rapid iteration and consistency. CSS Modules for scoped, component-encapsulated styles. CSS-in-JS for dynamic theming and colocation. Each approach solves a different problem — pick the right one.
Exact phrases: "CSS strategy", "CSS Modules", "CSS-in-JS", "utility-first", "Tailwind CSS", "styled-components", "Emotion", "CSS organization", "CSS architecture", "CSS approach", "styling approach", "how to style", "CSS decision".
CSS strategy recommendation with rationale, setup code, and organization pattern.
## Recommendation
<approach> — <rationale>
## Setup
<config, dependencies, file-structure>
## Usage
<component-example, naming-convention>
## Organization
<folder-structure, globals, utilities>
—
Compression footer: frontend-css/v1 | approach: <tailwind|modules|css-in-js> | perf: <runtime|zero>
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
4096 tokens
Project type?
├── Design system / component library -> CSS Modules or vanilla-extract (zero runtime, scoped)
├── Large app with many developers -> Tailwind CSS (consistent, low decision fatigue)
├── Highly themed / white-label app -> CSS-in-JS or CSS variables (dynamic theming)
├── Micro-frontend -> CSS Modules (isolation)
└── Small app / prototype -> Any — pick based on team preference
| Approach | Runtime | Scoping | Dynamic Themes | Bundle Size | Learning Curve |
|---|---|---|---|---|---|
| Utility-first (Tailwind) | Zero | N/A (utility classes) | Via CSS vars | Small (purged) | Low-Medium |
| CSS Modules | Zero | Automatic (hash) | Via CSS vars | Zero runtime | Low |
| styled-components | Runtime | Automatic (hash) | Native | ~12KB runtime | Medium |
| Emotion | Runtime | Automatic (hash) | Native | ~8KB runtime | Medium |
| vanilla-extract | Zero | Automatic (hash) | Via CSS vars | Zero runtime | Medium |
| Linaria | Zero | Automatic (hash) | Via CSS vars | Zero runtime | Medium |
| Stitches | Runtime | Automatic | Native | ~5KB runtime | Medium |
| Raw CSS/Sass | Zero | Manual (BEM) | Via CSS vars | Zero | Low |
src/
styles/
reset.css /* CSS reset */
variables.css /* CSS custom properties */
typography.css /* Font faces, text styles */
utilities.css /* Utility classes (if not Tailwind) */
animations.css /* Keyframes */
components/
Button/
Button.tsx
Button.module.css
Button.test.tsx
Card/
Card.tsx
Card.module.css
Card.test.tsx
pages/
Home/
Home.tsx
Home.module.css
/* Button.module.css */
.root {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border-radius: 6px;
font-weight: 500;
}
.primary {
background: var(--color-primary);
color: white;
}
.secondary {
background: transparent;
border: 1px solid var(--color-border);
}
export function Button({ variant = 'primary', ...props }: ButtonProps) {
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-transparent border border-gray-300 hover:bg-gray-50',
}
return (
<button
className={`inline-flex items-center gap-2 px-4 py-2 rounded-md font-medium transition-colors ${variants[variant]}`}
{...props}
/>
)
}
import styled, { css } from 'styled-components'
interface ButtonProps {
$variant: 'primary' | 'secondary'
$large?: boolean
}
export const StyledButton = styled.button<ButtonProps>`
display: inline-flex;
align-items: center;
gap: 8px;
padding: ${({ $large }) => ($large ? '12px 24px' : '8px 16px')};
border-radius: 6px;
font-weight: 500;
cursor: pointer;
${({ $variant }) =>
$variant === 'primary'
? css`
background: var(--color-primary);
color: white;
`
: css`
background: transparent;
border: 1px solid var(--color-border);
`}
`
// Button.css.ts
import { style, recipe } from '@vanilla-extract/css'
import { vars } from './theme.css'
export const button = recipe({
base: {
display: 'inline-flex',
alignItems: 'center',
gap: '8px',
padding: '8px 16px',
borderRadius: '6px',
fontWeight: 500,
},
variants: {
variant: {
primary: { background: vars.color.primary, color: 'white' },
secondary: { background: 'transparent', border: vars.color.border },
},
},
})
:root {
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-background: #ffffff;
--color-text: #1a1a1a;
--color-border: #e5e7eb;
--radius-sm: 4px;
--radius-md: 8px;
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-4: 16px;
}
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-nesting'), // or postcss-nested
require('autoprefixer'),
require('cssnano')({ preset: 'default' }),
],
}
/* Component-scoped responsive design */
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
Page layout (grid, sections)
-> Tailwind utility classes or CSS Grid in global styles
-> Reason: layout changes infrequently, benefits from standard grid
Component appearance (color, spacing, typography)
-> CSS Modules or styled-components
-> Reason: encapsulation, no class name collisions
Dynamic styles (theme-dependent, user-customizable)
-> CSS Variables
-> Reason: runtime theme switching without re-render
Animations
-> CSS keyframes in global animations.css
-> Reason: reusable, hardware-accelerated
/* Define layer order — lower priority first */
@layer reset, base, tokens, components, utilities, overrides;
/* Reset — lowest priority */
@layer reset {
*, *::before, *::after { box-sizing: border-box; margin: 0; }
}
/* Base — element defaults */
@layer base {
body { font-family: system-ui; line-height: 1.5; }
}
/* Components — scoped component styles */
@layer components {
.card { border-radius: 8px; padding: 16px; }
}
/* Utilities — highest priority (win over components) */
@layer utilities {
.mt-4 { margin-top: 16px; }
}
CSS Layers solve specificity wars by letting you define priority order explicitly. Tailwind v4 uses layers internally.
!important cascading indicates architectural problem.font-display: swap or font-display: optional for web fonts.| Aspect | Tailwind | CSS Modules | styled-components |
|---|---|---|---|
| Setup time | 5 min | 1 min | 5 min |
| Bundle impact | 0KB after purge | 0KB | ~12KB runtime |
| Design consistency | Excellent (constraint-based) | Manual | Manual |
| Learning curve | Medium | Low | Low |
| Dynamic theming | Via CSS vars | Via CSS vars | Native |
| Dev experience | Excellent with IDE plugin | Standard | Good with babel plugin |
| Migration difficulty | High to change | Low | Medium |
@layer has no performance cost — it is purely a cascade-ordering mechanism.tailwindcss — utility-first CSS framework with JIT compiler.postcss — CSS transformer (autoprefixer, nesting, custom media).sass — SCSS preprocessor with mixins, functions, variables.stylelint — CSS linter with rules for ordering, naming, specificity.vanilla-extract — zero-runtime CSS-in-JS with TypeScript.linaria — zero-runtime CSS-in-JS with Babel/Macro.critters — inline critical CSS for SSR frameworks.purgecss — remove unused CSS (used by Tailwind internally).lightningcss — Rust-based CSS parser/minifier (used by Vite, Parcel).cssnano — PostCSS-based CSS minifier.!important is never used unless overriding a third-party library.No artifact produced unless requested.
Next skill: frontend-tailwind-css — Tailwind-specific patterns, configuration, and optimization.
Carry forward: CSS approach selected, organization pattern, theming via CSS variables.
` interface EventObserver { onEvent(event: T): Promise; }
class EventBus { private observers: Set<EventObserver> = new Set(); subscribe(observer: EventObserver): void { this.observers.add(observer); } unsubscribe(observer: EventObserver): void { this.observers.delete(observer); } async emit(event: T): Promise { const results = Array.from(this.observers).map(o => o.onEvent(event)); await Promise.allSettled(results); } } `
config: defaults: timeout: 30s retryCount: 3 overrides: production: timeout: 60s retryCount: 5 development: timeout: 300s retryCount: 1
| Metric | Threshold | Severity | Action |
|---|---|---|---|
| Error rate | > 1% over 5min | Critical | Page on-call |
| p99 latency | > 2s over 5min | Warning | Investigate |
| Throughput drop | > 50% over 1min | Critical | Check upstream |
| Queue depth | > 1000 over 1min | Warning | Scale consumers |
| Disk usage | > 85% | Warning | Clean or expand |
| Memory usage | > 90% heap | Critical | Restart or scale |
| Anti-Pattern | Symptom | Root Cause | Solution |
|---|---|---|---|
| Premature optimization | Complex code for no measured benefit | Guessing instead of profiling | Measure first, optimize based on data |
| Copy-paste reuse | Duplicate code across codebase | Lack of abstraction | Extract shared logic into libraries |
| Gold-plating | Features with no current requirement | Over-engineering | YAGNI — build what's needed now |
| Magical thinking | Assumptions without validation | Skipping error handling | Handle all failure modes explicitly |
Cache hierarchy: L1 (in-memory local) → L2 (distributed Redis/Memcached) → L3 (CDN/Edge). Cache invalidation: TTL-based (simple, stale), event-based (complex, fresh), write-through (consistent, higher write latency), write-behind (fast writes, eventual consistency).
Is the project a design system or standalone app?
├── Design system → CSS Custom Properties + Shadow DOM or CSS Modules
└── Standalone app → Is SSR required?
├── Yes → CSS Modules or utility-first (Tailwind) with JIT
└── No → CSS-in-JS or utility-first (Tailwind)
Team prefers runtime or build-time?
├── Runtime → CSS-in-JS (emotion, styled-components)
└── Build-time → Tailwind or CSS Modules
How many developers work on CSS?
├── 1-3 → Loose conventions + BEM or Tailwind
├── 3-10 → Structured methodology (ITCSS, SMACSS) + lint rules
└── 10+ → Design token system + component-scoped styles + strict linting
Is the project multi-brand?
├── Yes → Design tokens with theme layers + CSS variables
└── No → Single design language with consistent tokens