Skip to main content

css

CSS conventions, layout systems, and modern patterns: predictable styles through low specificity and explicit cascade control. Invoke whenever task involves any interaction with CSS code — writing, reviewing, refactoring, debugging, or understanding stylesheets, SCSS, layout, or responsive design.

Source facts

Repository
xobotyi/cc-foundry
Last source activity
May 17, 2026 at 17:43
Detected SKILL.md language
English
Stars
22
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
7 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
css
description
CSS conventions, layout systems, and modern patterns: predictable styles through low specificity and explicit cascade control. Invoke whenever task involves any interaction with CSS code — writing, reviewing, refactoring, debugging, or understanding stylesheets, SCSS, layout, or responsive design.
# CSS **Predictability is the highest CSS virtue. If your styles require `!important` to work, restructure the cascade.** CSS rewards explicit, low-specificity selectors and intentional cascade ordering. Prefer boring, readable patterns over clever one-liners. ## References - **Layout** — [`${CLAUDE_SKILL_DIR}/references/layout.md`]: Flex shorthand values, grid details (subgrid, implicit rows, alignment), layout patterns - **Modern CSS** — [`${CLAUDE_SKILL_DIR}/references/modern-css.md`]: Extended modern CSS patterns and examples - **SCSS** — [`${CLAUDE_SKILL_DIR}/references/scss.md`]: `@forward` patterns, module configuration, built-in modules, file organization - **Responsive** — [`${CLAUDE_SKILL_DIR}/references/responsive.md`]: Extended responsive design patterns and examples - **Methodologies** — [`${CLAUDE_SKILL_DIR}/references/methodologies.md`]: Methodology patterns and architecture details ## Selectors and Specificity - Single class selectors by default — keep specificity flat at 0-1-0 - Never use ID selectors for styling — IDs are for anchors and JS hooks - Never qualify classes with elements — `.error` not `div.error` - Max nesting depth: 3 levels — deeper nesting couples CSS to DOM structure - Avoid `!important` — use cascade layers or restructure selectors instead; only valid use is in a low-priority reset layer for truly essential styles - Use `:where()` to zero-out specificity when needed — `:where(.card) .title` has 0-0-1 specificity - Use `:is()` with awareness — it takes the highest specificity of its arguments - Flatten nested selectors in SCSS — ability to nest does not mean you should ## Layout Systems ### Choosing Flexbox vs Grid | Use Case | System | | --------------------------------------------- | ------- | | One-dimensional flow (row or column) | Flexbox | | Two-dimensional layout (rows AND columns) | Grid | | Content-driven sizing | Flexbox | | Layout-driven sizing | Grid | | Component internals (nav items, card content) | Flexbox | | Page-level structure, complex arrangements | Grid | | Items need to wrap naturally | Flexbox | | Precise placement on named lines/areas | Grid | Both work together — a grid item can be a flex container and vice versa. ### Flexbox - Always use the `flex` shorthand — it sets intelligent defaults. See `${CLAUDE_SKILL_DIR}/references/layout.md` for the full shorthand value table - `flex-flow: row wrap` combines `flex-direction` and `flex-wrap` - Use `flex-wrap` with a `flex` basis for responsive layouts without media queries: `flex: 1 1 300px` wraps items when they can't maintain 300px minimum - Centering: `display: flex; align-items: center; justify-content: center` or `margin: auto` on a flex child - `gap` over margin hacks — works in both flexbox and grid - Avoid `justify-content: space-between` with wrap — causes orphan gaps; prefer `gap` + `flex-wrap` ### CSS Grid - `repeat(auto-fit, minmax(250px, 1fr))` is the canonical responsive grid — no media queries needed - Prefer `auto-fit` over `auto-fill` — `auto-fit` expands columns to fill space; `auto-fill` keeps empty tracks - Use named grid areas for page-level layouts — they auto-create named lines - Never hardcode `px` widths on grid items — use `fr`, `minmax()`, or `auto` - `grid-auto-flow: dense` fills visual holes — use carefully, it breaks visual/source order alignment (a11y concern) - Never use `order` in ways that break logical reading order - See `${CLAUDE_SKILL_DIR}/references/layout.md` for subgrid, implicit rows, alignment shorthands, and negative line numbers ### General Layout Rules - Never use `float` for layout — floats are for wrapping text around images - Intrinsic sizing first — use `flex-wrap`, `min()`, `max()`, `clamp()` before reaching for media queries ## CSS Nesting - Use `&` for pseudo-classes/elements and compound selectors — `&:hover`, `&::before`, `&.active` - Omit `&` for descendant selectors — `.card { .title {} }` works - `&` is required when the nested selector starts with a type selector — `& p {}` not `p {}` - Nesting at-rules (`@media`, `@supports`, `@container`) nest directly inside rules - Specificity: `:is()` wrapping applies in nesting — be aware that specificity may differ from the equivalent unnested selector - Max depth: 3 levels — same rule as flat CSS ## Cascade Layers (`@layer`) - Declare all layers at the top of the stylesheet in a single statement: `@layer reset, defaults, themes, components, utilities;` - First declared = lowest priority; un-layered styles always beat layered styles - `!important` reverses layer order — `!important` in the lowest layer wins over `!important` in higher layers - Import third-party CSS into sub-layers: `@import url('vendor.css') layer(vendor.bootstrap);` - Use `revert-layer` to roll back to the previous layer's value - `!important` in low layers is intentional — it means "this style is essential, don't override" - Don't create layers per-component — layers manage cascade priority between categories (reset vs component vs utility), not scope - Nested layers: `@layer components { @layer buttons, cards; }` — access via `@layer components.buttons` - Anonymous layers (`@layer { }`) can't be appended to later ## Container Queries - Define containment: `container-type: inline-size` on the wrapper - Name containers for targeting: `container: card / inline-size` - Query by name: `@container card (width > 400px) { }` - Unnamed queries hit the nearest ancestor container ### Container Query Units - `cqw` / `cqh` — 1% of container width / height - `cqi` / `cqb` — 1% of container inline / block size - `cqmin` / `cqmax` — smaller / larger of `cqi` or `cqb` Use `cqi` instead of `vw` for container-scoped fluid values: `font-size: clamp(1rem, 2.5cqi + 0.5rem, 2rem)` ## Responsive Design ### Responsive Hierarchy Design from the inside out — use the right tool for each level: - **Content-driven** — Flexbox wrapping, `min()`/`max()`/`clamp()`: always — baseline - **Container-driven** — Container queries, `cqi`/`cqw` units: component adapts to parent - **Viewport-driven** — Media queries, `vw`/`vh`/`dvh`: page-level layout changes - **User preference** — `prefers-*` media queries: color scheme, motion, contrast ### Core Rules - Mobile-first — default styles for small screens, enhance upward - Content-driven breakpoints — let content decide, not device sizes - `rem` for breakpoints: `@media (width >= 45rem)` not `(min-width: 768px)` - Use modern range syntax: `@media (768px <= width < 1024px)` - Logical properties for layout: `margin-inline-start` not `margin-left` - Container queries for component-level adaptation; media queries only for viewport-dependent elements (nav, header) - Respect user preferences: `prefers-reduced-motion`, `prefers-color-scheme`, `prefers-contrast` - Single container max-width pattern: `width: min(100% - 2rem, 75rem); margin-inline: auto` — avoid multiple `max-width` values at different breakpoints ### Fluid Sizing - `clamp(min, preferred, max)` for fonts, spacing, and container widths - Build a fluid type scale with custom properties: `--step-0: clamp(1rem, 0.5rem + 1.5vw, 1.25rem)` - Never use `vw` alone for font size — it blows up on large screens; always pair with `clamp()` and `rem` - Use `cqi` instead of `vw` for container-scoped fluid values ### Logical Properties Use logical properties for layout-sensitive values (margins, padding, borders, text alignment, positioning offsets). Physical properties are fine for visual effects not affected by writing direction (e.g., box-shadow offsets). - `left` / `right` → `inline-start` / `inline-end` - `top` / `bottom` → `block-start` / `block-end` - `width` / `height` → `inline-size` / `block-size` - `margin-left` → `margin-inline-start` - `padding-top` → `padding-block-start` - `text-align: left` → `text-align: start` Shorthands: `margin-block: 1rem 2rem` (block-start, block-end); `margin-inline: auto` (both inline directions). ### User Preference Queries - Color scheme: declare `color-scheme: light dark` on `:root` and use `@media (prefers-color-scheme: dark)` for overrides - Reduced motion: either remove motion in `prefers-reduced-motion: reduce` or add motion only in `prefers-reduced-motion: no-preference` (progressive enhancement approach) - High contrast: `@media (prefers-contrast: more)` - Interaction: `@media (hover: hover)` for hover effects on capable devices; `@media (pointer: coarse)` for touch targets (min 44px) ### Responsive Images - `img { max-width: 100%; height: auto; display: block; }` - Use `aspect-ratio` + `object-fit: cover` for hero images ## The `:has()` Selector Select elements based on descendants or siblings — the "parent selector." - Anchor to specific elements, not `body`, `:root`, or `*` — broad anchors force expensive re-evaluation on every DOM change - Use direct child (`>`) or sibling (`+`, `~`) combinators inside `:has()` to limit traversal scope - Cannot nest `:has()` inside `:has()` - Pseudo-elements are not valid inside `:has()` - `.layout:has(> .sidebar-open)` (good) not `body:has(.sidebar-open)` (bad) ## Custom Properties - Define design tokens on `:root` — scope overrides to components - Semantic naming: `--color-text-primary` not `--dark-gray` - Use kebab-case; prefix with category: `--color-`, `--spacing-`, `--font-` - Provide fallbacks for component-level variables: `var(--button-bg, var(--color-primary))` - Custom properties are case-sensitive — `--my-color` differs from `--My-Color` - Custom properties inherit by default (unlike most CSS properties) - Use `@property` for typed, animatable custom properties — enables type checking (invalid values fall back to `initial-value`), controlled inheritance (`inherits: false`), and transitions on custom properties ## View Transitions - `view-transition-name` must be unique per page at transition time - Keep transitions short — 200-400ms for UI, longer for page-level - Always respect `prefers-reduced-motion: reduce` for view transitions - Same-document (SPA): `document.startViewTransition(() => { /* update DOM */ })` - Cross-document (MPA): `@view-transition { navigation: auto; }` - Named transitions target specific elements via `::view-transition-group(name)` ## Box Model and Sizing - Always set `box-sizing: border-box` globally via reset - `rem` for font sizes and breakpoints — respects user preferences - `em` for component-relative spacing (padding that scales with font size) - Fluid sizing with `clamp()` — replace manual breakpoint ladders - `aspect-ratio` over padding hacks for maintaining proportions - No units on zero values — `margin: 0` not `margin: 0px` (except where required: `flex: 0 0 0px`) - Leading zero on decimals: `opacity: 0.5` not `opacity: .5` - Shorthand hex where possible: `#ebc` not `#eebbcc` ## SCSS / Dart Sass ### Module System - `@use` and `@forward` only — `@import` is deprecated (Dart Sass 1.80.0), removed in 3.0.0 - `@use` must appear before any rules except `@forward` - Namespace defaults to the last component of the URL (without extension) - Members are scoped to the loading file — not globally available - Each module loaded exactly once — no duplicate CSS output - Namespace access: `variables.$primary` not global `$primary` - No-namespace `@use 'variables' as *` — use sparingly, only for own files - `math.div()` for division — the `/` operator is deprecated - Prefix private members with `-` or `_` - Prefer mixins over `@extend` — more predictable output; `@extend` produces unexpected selectors and doesn't work across media queries - Max nesting: 3 levels `@forward` re-exports modules, supports prefixing and visibility control. Module configuration uses `!default` variables and `@use ... with ()`. See `${CLAUDE_SKILL_DIR}/references/scss.md` for `@forward` patterns, configuration passthrough, built-in module usage, and file organization conventions. ### Migration Use the official migrator: `sass-migrator module --migrate-deps entrypoint.scss`. For built-in functions only: `sass-migrator module --built-in-only entrypoint.scss`. ## CSS Methodologies ### BEM (Block Element Modifier) - Blocks are standalone components: `.card`, `.nav`, `.form` - Elements are parts of a block (double underscore): `.card__title`, `.card__image` - Modifiers are variations (double hyphen): `.card--featured`, `.card__title--bold` - Never nest elements: `.card__header__title` is wrong — flatten to `.card__title` or create a new block - Modifiers don't exist alone — always pair with base class: `class="card card--featured"` - Use BEM in team projects, large codebases, projects without scoped styles - Skip BEM when using CSS Modules, utility-first CSS, or small projects ### CSS Modules - Use simple, descriptive class names — scoping eliminates conflict risk - One module per component - Compose shared styles: `composes: resetButton from './shared.module.css'` - Global escape hatch: `:global(.utility-class)` when needed - Pair with custom properties for theming (variables aren't scoped) ### Architecture (ITCSS) Organize styles by specificity, low to high: Settings → Tools → Generic → Elements → Objects → Components → Utilities. Maps naturally to cascade layers: `@layer settings, generic, elements, objects, components, utilities;` ## Formatting - 2-space indentation, no tabs - One declaration per line - Semicolon after every declaration including the last - Space after colon: `color: red` not `color:red` - Opening brace on same line as selector - Blank line between rules - Lowercase everything (selectors, properties, values, hex colors) - Single quotes for attribute selectors and font names - Group declarations by category: layout → box model → typography → visual → interaction ## Application When **writing** CSS: - Apply all conventions silently — don't narrate each rule being followed. - Use intrinsic sizing and fluid techniques before media queries. - If an existing codebase contradicts a convention, follow the codebase and flag the divergence once. When **reviewing** CSS: - Cite the specific violation and show the fix inline. - Don't lecture or quote the rule — state what's wrong and how to fix it. ``` Bad review comment: "According to CSS best practices, you should avoid using ID selectors for styling because they have high specificity." Good review comment: "`#header` -> `.header` -- IDs create specificity 1-0-0, difficult to override." ``` ## Integration The coding skill governs workflow; this skill governs CSS implementation choices. For SCSS, this single skill covers both CSS and SCSS conventions.
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub