浏览器

CSS

围绕 CSS 机制排查问题并编写组件样式表,而不是凭感觉试错。

它能做什么

一个围绕布局、层叠与渲染原理组织的 CSS 编写与调试技能。它先诊断再下笔——先指出堆叠上下文、flex 尺寸算法或 margin 合并的根因,再给出修复;并强制执行"只动画 transform/opacity""浮层走 top layer"等硬规则,按可配置的浏览器支持与无障碍基线输出。输出形态可配置:仅改动声明的 diff 或整张重写表,带机制解释或仅一行修复,支持原生 CSS、Sass、Tailwind 或 CSS-in-JS 语法。

什么时候用它

  • 弹窗被页眉盖住、z-index 无效、sticky 不生效、内容溢出
  • 把旧样式表迁移到 :has()、@layer、原生嵌套或容器查询
  • 从零搭建卡片栅格、表单控件美化或带粘性表头的数据表格
  • 修复 CLS、字体闪烁、动画卡顿或打印/PDF 输出异常

技能文档

User preferences and memory live in ~/Clawic/data/css/ (see setup.md on first use, memory-template.md for the file format). If you have data at an old location (~/css/ or ~/clawic/css/), move it to ~/Clawic/data/css/.

Configuration

User-dependent variables. Defaults apply until the user states a preference; store them in ~/Clawic/data/css/config.yaml.

VariableTypeDefaultEffect
authoring_modeplain-css | sass | tailwind | css-in-jsplain-cssSyntax of every emitted example, and which advice in architecture.md applies (layers and nesting vs utility ordering vs zero-runtime extraction)
browser_supportevergreen | widely-available | legacyevergreenGates which features ship bare vs behind @supports: legacy also adds vendor-prefixed fallbacks and blocks the Chromium-first features flagged in compatibility.md
naming_conventionbem | utility | css-modules | nonenoneClass names in examples and the specificity ceiling enforced in reviews (architecture.md — Keeping It Clean)
rem_basenumber px (10-16)16Every px→rem conversion, including the fluid-type derivation in responsive.md (rem term = px ÷ rem_base)
a11y_targetaa | aaaaaWhich row of Accessibility Floor gates output: AA = 4.5:1 body / 24×24 targets, AAA = 7:1 body / 44×44 targets
explanation_depthmechanism | fix-onlymechanismHow much of the why ships with each answer: mechanism names the cause (stacking context, flex sizing) before the declaration; fix-only emits the declaration plus one line
output_shapediff | full-sheetdiffEmitted code: diff = only the changed declarations in context; full-sheet = the complete rewritten stylesheet or component block

Preference areas to record as the user reveals them:

  • tooling — build chain (PostCSS, Lightning CSS, bundler), formatter and lint rules, whether native nesting is allowed
  • conventions — spacing and type scale in use, token naming, file-per-component vs grouped sheets
  • output — beyond explanation_depth and output_shape: comment density in emitted CSS, longhand vs shorthand, whether fallbacks and @supports branches are shown or assumed, how much of the trade-off to state before choosing
  • platform — target surfaces (app, marketing site, HTML email, print/PDF), device mix, whether RTL or CJK is in scope
  • risk posture — appetite for Chromium-first features, tolerance for !important in third-party overrides, how loudly to flag accessibility regressions
  • constraints — banned techniques (CSS-in-JS, utility classes, @import), inherited legacy stylesheets that must keep working

When To Use

  • Debugging layout: z-index that won't apply, overflow, dead height: 100%, broken position: sticky, mystery horizontal scroll
  • Building components and starting stylesheets: reset and base layers, flexbox/grid patterns, centering, forms, tables, overlays, responsive behavior without media-query sprawl
  • Production hardening: layout shift, animation jank, font loading, print output, the accessibility floor
  • Replacing JS or preprocessor hacks with native CSS (:has(), @layer, @scope, container queries, scroll snap, anchor positioning)
  • Cross-engine work: a rule that lands in Chrome and not Safari, RTL mirroring, HTML email constraints
  • Not for visual design decisions (palettes, spacing scales, typography choice) — this skill covers mechanics, not taste

Quick Reference

SituationPlay
z-index ignored despite a huge valueStacking Contexts below — find the context root; never just bump the number
Flex item overflows / text won't truncatemin-width: 0 on the flex child (default min-width is min-content)
The rule is written but nothing changesdebugging.md — symptom→cause chains, starting with "is it even matching?"
Breaks with real content, sticky dead, footer floats, margin leakslayout.md
Component must adapt to its container; fluid type; mobile viewport bugsresponsive.md
Specificity fight, @layer, :has(), custom-property gotchasselectors.md
Jank, layout shift, slow paint, font flashperformance.md
Transition never fires, enter/exit animation, view transitions, reduced motionanimations.md
Line-height inheritance, measure, variable fonts, hyphenation, tabular numberstypography.md
oklch vs hsl, color-mix(), gradient banding, wide gamutcolor.md
Dark mode, design tokens, multi-brand, theme flash on loadtheming.md
Inputs, selects, checkboxes, validation states, autofill stylingforms.md
Modal behind the header, dropdown clipped, tooltip placementoverlays.md
Scroll snap, custom scrollbars, anchor link lands under the sticky headerscrolling.md
Data table: sticky header, responsive behavior, column sizingtables.md
Shadows, filters, masks, clip-path, blend modes, 3D transformseffects.md
Starting a stylesheet: what goes in the reset and base layers, in what orderreset.md
Sheet organization, layer strategy, nesting, Sass migration, shadow DOMarchitecture.md
Works in Chrome, breaks in Safari or Firefox; HTML emailcompatibility.md
Print or PDF output wrongprint.md
RTL mirroring, CJK line breaking, logical properties, text expansioninternationalization.md
Anything else CSSCore Rules below, then debugging.md to name the mechanism

Core Rules

  1. Diagnose before adding CSS: reproduce, isolate in DevTools, name the mechanism (stacking context, flex sizing algorithm, margin collapse). A property added without a named mechanism is the next bug.
  2. Animate only transform and opacity — the only common properties that skip layout and paint. Frame budget = 1000ms / 60fps ≈ 16.7ms for style, paint, and your JS combined; one layout-triggering animation spends it alone.
  3. One centering default: parent display: grid; place-content: center. Escape hatch: position: absolute; inset: 0; margin: auto when the child must overlay (needs a resolvable size, e.g. width: fit-content).
  4. Never bare viewport units for text. font-size: clamp(1rem, 0.77rem + 0.91vw, 1.5rem) — the rem term is what keeps browser zoom and user font-size working; pure-vw text fails WCAG 1.4.4 (resize to 200%). Derivation of the numbers: responsive.md.
  5. Size intrinsically first (min(), clamp(), fit-content, auto-fit grids), media queries second, container queries when one component lives at different widths.
  6. !important in component code is a debt marker. Order wars belong in @layer — unlayered author styles beat all layered ones regardless of specificity (selectors.md).
  7. Overlays belong in the top layer, not high in the z-index scale. .showModal() and popover escape every stacking context and every overflow: hidden ancestor; a z-index arms race means the wrong mechanism is in use (overlays.md).
  8. A component styles its inside, never its outside: no margin, no width, no position on the component root — the parent layout owns placement. Components that set their own outer geometry break on the second reuse and get "fixed" with !important.

Stacking Contexts

The single most common CSS debugging failure: raising z-index on an element trapped inside a context.

  • Context creators (memorize): positioned element with z-index, flex/grid child with z-index, opacity < 1, transform, filter, backdrop-filter, will-change, contain: layout or paint, position: fixed/sticky, isolation: isolate.
  • Inside a context, z-index competes only among siblings of that context. A child's z-index: 9999 never escapes its parent's z-index: 1.
  • Debug procedure, in order: (1) walk up from the losing element to its first context-creating ancestor; (2) same for the winning element; (3) compare those two ancestors — that comparison decides the paint order; (4) fix z-index there, or delete the accidental trigger (usually a leftover transform or opacity from an animation).
  • isolation: isolate creates a context with zero visual side effects — use it to cap a component's internal z-index so it can't leak out.
  • transform, filter, and will-change also make the element the containing block for position: fixed descendants — the fixed element behaves as absolute with no warning. Same walk-up diagnosis.
  • Elements promoted to the top layer (modal ``, popover) ignore all of the above: they paint above the page and above each other in open order (rule 7).

Flexbox and Grid Mental Model

  • flex: 1 = 1 1 0%: ALL space divided equally. flex: auto = 1 1 auto: only leftover space divided, so larger content keeps a larger track. Choose per intent; equal columns need basis 0.
  • Flex children default to min-width: min-content — the root cause of both overflow and un-truncatable text. Release with min-width: 0 (or overflow: hidden). Column direction: same story with min-height.
  • 1fr means minmax(auto, 1fr): the track refuses to shrink below its content. grid-template-columns: 1fr 1fr is NOT 50/50 with unequal content — write minmax(0, 1fr) for true halves.
  • auto-fit collapses empty tracks (remaining cards stretch); auto-fill keeps them (cards hold max width). Card grid default: repeat(auto-fit, minmax(min(250px, 100%), 1fr)) — the inner min() prevents overflow on viewports under 250px.
  • gap never collapses; margins collapse (vertical, block layout only, including parent-child bleed-through). Prefer gap and treat margin collapse as legacy behavior to route around (layout.md).
  • margin: auto on a flex/grid child absorbs free space: margin-inline-start: auto on the last nav item is the entire "push right" pattern.
  • Grid when the parent decides both axes (page scaffolding, card grids, overlapping layers via named areas); flex when the children decide and simply wrap (toolbars, tag lists, button rows).

Modern CSS Worth Using

Compatibility floor: everything here is in all three engines unless marked; version-sensitive items are dated in compatibility.md.

  • :has() — parent and previous-sibling selection; kills a whole class of state-mirroring JS (selectors.md for patterns and cost).
  • @starting-style + transition-behavior: allow-discrete — transition from display: none; replaces enter-animation JS (all engines since mid-2024).
  • light-dark() + color-scheme — one declaration per token instead of a duplicated dark block (all engines since 2024; theming.md).
  • text-wrap: balance on headings — engines skip long blocks (Chromium caps at 6 lines), so it is safe to apply to all headings.
  • scrollbar-gutter: stable on scroll containers — reserves the gutter, no shift when the scrollbar appears.
  • overscroll-behavior: contain on modals and drawers — stops scroll chaining into the page.
  • scroll-snap-type + scroll-snap-align — carousels without JS (scrolling.md).
  • aspect-ratio — reserve media space before load (layout-shift numbers: performance.md).
  • accent-color — form controls on brand without rebuilding them (forms.md).
  • @scope and native nesting — component boundaries without naming conventions; specificity traps in architecture.md.
  • Individual transforms (translate, rotate, scale) — compose in a fixed order and animate independently, no more one-property transform collisions.
  • Anchor positioning (anchor-name, position-area) — tethered popovers without a positioning library; still needs a fallback, see overlays.md.

Accessibility Floor

Canonical home for these numbers — other files point here.

  • Contrast (WCAG 2.2 AA): 4.5:1 body text; 3:1 for large text (≥24px, or ≥18.66px bold) and for UI components and focus indicators (1.4.3, 1.4.11). AAA raises body text to 7:1 and large text to 4.5:1 (1.4.6) — applies when a11y_target: aaa.
  • Touch targets: ≥24×24 CSS px is the AA minimum (2.5.8); 44×44 matches Apple HIG and WCAG AAA (2.5.5) — use 44 for primary mobile actions and whenever a11y_target: aaa.
  • Text survives 200% zoom (1.4.4): rem-based sizes plus the clamp rule (Core Rule 4).
  • Motion is opt-in: wrap animation in @media (prefers-reduced-motion: no-preference) rather than overriding after the fact.
  • Style :focus-visible; never outline: none without a replacement in the same rule.
  • @media (forced-colors: active): system colors replace yours — check borders and focus still exist there.
  • Dark mode: @media (prefers-color-scheme: dark) plus color-scheme: light dark so form controls and scrollbars follow.
  • Content reflows to a 320px-wide viewport without two-axis scrolling (1.4.10) — the practical floor for "does it work zoomed on a phone".
  • Three different hides, chosen deliberately: display: none / visibility: hidden remove content from the accessibility tree; aria-hidden hides from assistive tech while staying visible; screen-reader-only text needs the clip pattern — position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap.

Output Gates

Before shipping a stylesheet or component styles, verify:

  • Hostile content survives: longest word (URL, German compound), empty state, missing image, 3-line title where you designed one line?
  • 200% zoom and a 320px viewport reflow without horizontal scroll?
  • Every interactive element has a visible :focus-visible style and meets the contrast and target-size rows above?
  • Animation wrapped in prefers-reduced-motion: no-preference, and only transform/opacity in the frame loop?
  • Media and embeds have reserved space (aspect-ratio or width/height attributes)?
  • No !important outside a third-party override, and no new selector above single-class specificity?
  • Dark mode checked if the project themes, and RTL checked if internationalization.md is in scope?

Traps

TrapWhy it failsDo instead
Bumping z-index to 9999Element is inside a stacking context; only the context root competes outsideWalk-up procedure (→ Stacking Contexts)
Animating height/top/left/marginLayout runs every frame and blows the 16.7ms budget (Core Rule 2)transform; for height-to-auto, the grid-rows trick (→ layout.md)
overflow: hidden to kill a stray scrollbarHides the symptom and creates a scroll container: breaks sticky descendants, clips shadows and focus ringsFind the overflowing element first; when it cannot be removed, html { overflow-x: clip } — clip creates no scroll container, so sticky survives (→ layout.md)
var(--x, fallback) as a safety netA declared-but-invalid value skips the fallback ("invalid at computed-value time")@property with initial-value (→ selectors.md)
Global will-change or translateZ(0) "GPU hints"Every layer holds GPU memory; hundreds of layers slow compositingwill-change only on elements actually animating, only while animating (→ performance.md)
100vh full-screen sectionsMobile browser UI overlaps the bottom of the section100svh; dvh only when live resize is acceptable (→ responsive.md)
!important to win a specificity fightEscalation is one-way; the next override needs another !important@layer ordering (→ selectors.md)
:empty for empty statesWhitespace text nodes count as content in most enginesControl the markup, or a class set by the renderer
transition: allAnimates properties added later — including layout ones — and turns theme swaps into visible sweepsEnumerate the properties you mean (→ animations.md)
:invalid for error stylingMatches an untouched empty required field on first paint: the form is red before typing:user-invalid (→ forms.md)
line-height: 150%Percentages inherit the COMPUTED value, so a big heading inherits the body's pixel leadingUnitless line-height: 1.5 (→ typography.md)
display: none for screen-reader-only textRemoves it from the accessibility tree — nobody hears itThe clip pattern (→ Accessibility Floor)
text-align: left and margin-left in a themeable productThe first RTL locale mirrors everything except your CSSLogical properties (→ internationalization.md)

Where Experts Disagree

  • Selector performance: the old guard writes selectors for right-to-left matching cost; modern engines bucket by rightmost simple selector, making it negligible. Boundary: only act on a DevTools trace showing Style/Recalculate cost — usually :has() or universal selectors on large, frequently-mutating DOMs (performance.md).
  • Utility-first vs handwritten CSS: utilities win on team consistency and dead-code elimination; handwritten wins for animation-heavy and design-led work. Boundary: follow whichever the codebase already uses; never mix systems inside one component.
  • CSS-in-JS: colocation and typed themes vs runtime cost. Boundary: server-rendered, performance-critical pages want zero-runtime extraction (or plain CSS + @layer); internal dashboards can afford runtime styling.
  • Contrast math: WCAG 2.x ratios are the legally referenced standard but misjudge dark backgrounds and thin type; APCA (the WCAG 3 candidate) models them better and is not yet normative. Boundary: ship to WCAG 2.2 numbers for compliance, use APCA as a tiebreaker when two palettes both pass.

More Clawic skills, get them at https://clawic.com/skills/css (install if the user confirms):

  • html - semantic structure and document-level concerns the CSS hooks into
  • frontend - component architecture, frameworks, and build tooling around the styles
  • animations - motion design and choreography beyond single-property transitions
  • accessibility-audit - full WCAG review beyond the CSS floor here
  • design-system - tokens, theming, and scaling styles across a product

Feedback

Part of Clawic, the verified skill library. Get this skill: https://clawic.com/skills/css.

常见问题

会不会帮忙挑配色、间距比例或字体?
不会。本技能只覆盖 CSS 机制,审美层面的取舍(配色、间距、字体选择)明确不在范围内。
支持 Sass、Tailwind 或 CSS-in-JS 吗?
支持。authoring_mode 切换生成的语法,并决定走哪套架构建议(@layer 与原生嵌套 vs 工具类顺序 vs 零运行时提取)。
Safari 或 HTML 邮件怎么办?
browser_support=legacy 时会补齐厂商前缀并屏蔽 Chromium 优先的特性;另有专门的兼容性文件标注跨引擎和邮件客户端风险。

相关技能

诊断并交付能在生产环境编译生效的 Tailwind v3/v4 标记、主题与构建配置

129 次安装5 星标

Build polished, conversion-aware frontends with strong visual taste, clear hierarchy, and production-grade HTML/CSS/JS. Landing pages, dashboards, components...

59 次安装2 星标

用可量化的层级、间距、字号、配色与版式规则,绘制并诊断视觉作品。

作者 Iván137 次安装5 星标

针对 Vue 3 响应式、组件、路由和性能问题,依据控制台报错与代码形态给出具体修复方案。

121 次安装8 星标

按规则构建、调试和审查 React 应用,覆盖组件、状态、表单、性能与 React 19 特性。

245 次安装3 星标

排查并修复 Svelte 与 SvelteKit 的响应式、SSR 与构建问题,并把 Svelte 4 代码迁移到 runes。

62 次安装3 星标

Iván 的更多技能

浏览全部技能

执行 Git 操作(提交、分支、合并、变基、冲突解决与恢复)时强制套用安全规则。

作者 Iván527 次安装31 星标

用可量化的层级、间距、字号、配色与版式规则,绘制并诊断视觉作品。

作者 Iván137 次安装5 星标

以系统方式规划并执行自学:从出口测试倒推课程,加入间隔复习与刻意练习,产出可验证的迁移证据。

作者 Iván93 次安装3 星标

针对你的 Azure 订阅,做架构设计、故障排查、安全加固与成本优化

作者 Iván86 次安装2 星标

按配置的 JDK 版本诊断 Java 与 JVM 问题(从 NPE 到容器 OOM),给出可直接套用的代码与配置。

作者 Iván130 次安装9 星标

在 EC2、Lambda、RDS、VPC、IAM 等核心服务上做架构、排查、加固与成本优化,每次建议都给出月度开销与故障域。

作者 Iván138 次安装2 星标