Skill: ivangdavila/css (version 1.0.1)

--- name: CSS slug: css version: 1.0.1 description: Write modern CSS with proper stacking contexts, layout patterns, responsive techniques, and performance optimization. metadata: {"clawdbot":{"emoji":"🎨","os":["linux","darwin","win32"]}} --- ## When to Use User needs CSS expertise — from layout challenges to production optimization. Agent handles stacking contexts, flexbox/grid patterns, responsive design, performance, and accessibility. ## Quick Reference | Topic | File | |-------|------| | Layout patterns | `layout.md` | | Responsive techniques | `responsive.md` | | Selectors and specificity | `selectors.md` | | Performance optimization | `performance.md` | ## CSS Philosophy - Layout should be robust—work with any content, not just demo content - Use modern features—they have better browser support than you think - Prefer intrinsic sizing—let content determine size when possible - Test with extreme content—longest names, missing images, empty states ## Stacking Context Traps - `z-index` only works with positioned elements—or flex/grid children - `isolation: isolate` creates stacking context—contains z-index chaos without position - `opacity < 1`, `transform`, `filter` create stacking context—unexpected z-index behavior - New stacking context resets z-index hierarchy—child z-index:9999 won't escape parent ## Layout Traps - Margin collapse only vertical, only block—flex/grid children don't collapse - `overflow: hidden` on flex container can break—use `overflow: clip` if you don't need scroll ## Flexbox Traps - `flex: 1` means `flex: 1 1 0%`—basis is 0, not auto - `min-width: 0` on flex child for text truncation—default min-width is min-content - `flex-basis` vs `width`: basis is before grow/shrink—width is after, basis preferred - `gap` works in flex now—no more margin hacks for spacing ## Grid Traps - `fr` units don't respect min-content alone—use `minmax(min-content, 1fr)` - `auto-fit` vs `auto-fill`: fit collapses empty tracks, fill keeps them - `grid-template-columns: 1fr 1fr` is not 50%—it's equal share of REMAINING space - Implicit grid tracks can surprise you—items placed outside explicit grid still appear ## Responsive Philosophy - Start mobile-first—`min-width` media queries, base styles for mobile - Container queries: `@container (min-width: 400px)`—component-based responsive - `container-type: inline-size` on parent required—for container queries to work - Test on real devices—emulators miss touch targets and real performance ## Sizing Functions - `clamp(min, preferred, max)` for fluid typography—`clamp(1rem, 2.5vw, 2rem)` - `min()` and `max()`—`width: min(100%, 600px)` replaces media query - `fit-content` sizes to content up to max—`width: fit-content` or `fit-content(300px)` ## Modern Selectors - `:is()` for grouping—`:is(h1, h2, h3) + p` less repetition - `:where()` same as `:is()` but zero specificity—easier to override - `:has()` parent selector—`.card:has(img)` styles card containing image - `:focus-visible` for keyboard focus only—no outline on mouse click ## Scroll Behavior - `scroll-behavior: smooth` on html—native smooth scroll for anchors - `overscroll-behavior: contain`—prevents scroll chaining to parent/body - `scroll-snap-type` and `scroll-snap-align`—native carousel without JS - `scrollbar-gutter: stable`—reserves scrollbar space, prevents layout shift ## Shorthand Traps - `inset: 0` equals `top/right/bottom/left: 0`—less repetition - `place-items` is `align-items` + `justify-items`—`place-items: center` centers both - `margin-inline`, `margin-block` for logical properties—respects writing direction ## Performance Mindset - `contain: layout` isolates repaints—use on independent components - `content-visibility: auto` skips offscreen rendering—huge for long pages - `will-change` sparingly—creates layers, uses memory - Avoid layout thrash—batch reads and writes to DOM ## Accessibility Baseline - `prefers-reduced-motion: reduce`—disable animations for vestibular disorders - `prefers-color-scheme`—`@media (prefers-color-scheme: dark)` for dark mode - `forced-colors: active`—adjust for Windows high contrast - Focus indicators must be visible—don't rely on color alone

path: layout.md
content: # Layout Patterns

## Flexbox Patterns

- `display: flex; gap: 1rem` for spaced rows—clean and simple
- `justify-content: space-between` for nav/footer with logo and links
- `flex-wrap: wrap` + `flex: 1 1 300px` for card grids—responsive without media queries
- `align-items: stretch` is default—children fill height unless explicitly sized

## Grid Patterns

- `grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))` for responsive cards
- `grid-template-areas` for complex layouts—visual and maintainable
- `grid-column: 1 / -1` for full-width items in grid
- Subgrid for aligned nested content—parent grid lines extend to children

## Centering Patterns

- `place-items: center` on grid—centers both axes
- `margin: auto` on flex child—pushes to edges or centers
- `position: absolute; inset: 0; margin: auto` for overlay centering
- Grid/flex on parent, auto margins on child—most robust approach

## Sticky Patterns

- `position: sticky; top: 0` for sticky headers—needs scrolling ancestor
- Sticky doesn't work with `overflow: hidden` on ancestor—clips the sticky area
- Multiple stickies can stack—adjust `top` values to account for each other
- Use `z-index` with sticky—it stacks above siblings

## Overflow Handling

- `overflow: hidden` clips content—use `overflow: clip` if you don't need scroll
- `overflow: auto` vs `scroll`: auto only shows scrollbar when needed
- `text-overflow: ellipsis` needs `overflow: hidden` AND `white-space: nowrap`
- `overflow-x: clip; overflow-y: visible` is tricky—often becomes `overflow-x: clip; overflow-y: auto`

## Box Model Patterns

- `box-sizing: border-box` on everything—width includes padding and border
- Margin collapse only vertical, only block—flex/grid children don't collapse
- `padding: max(1rem, 5vw)` for responsive padding—clamped minimum
- `outline` doesn't affect layout—useful for debugging without side effects

## Logical Properties

- `margin-inline`, `padding-block` for writing-mode aware spacing
- `inset-inline-start` instead of `left`—respects RTL
- `inline-size` instead of `width`—adapts to writing direction
- Use logical properties for international-ready CSS

## Common Layout Bugs

- 100% height not working—parent chain must also have defined height or use flexbox
- Content overflows container—`min-width: 0` on flex children
- Footer not at bottom—use flexbox or grid on body, `margin-top: auto` on footer
- Unexpected scrollbar—check for content slightly bigger than container


path: performance.md
content: # Performance Optimization

## Render Pipeline Understanding

- Style → Layout → Paint → Composite—changes early in pipeline are expensive
- `transform` and `opacity` only trigger composite—cheapest animations
- `width`, `height`, `margin` trigger layout—expensive, avoid animating
- `background-color`, `box-shadow` trigger paint—moderate cost

## Containment

- `contain: layout` isolates layout calculations—changes inside don't affect outside
- `contain: paint` creates paint boundary—clips like overflow:hidden
- `contain: strict` is all containment—maximum isolation, use on independent widgets
- `content-visibility: auto` skips rendering offscreen—huge savings on long pages

## Animation Performance

- Only animate `transform` and `opacity`—everything else causes repaint
- Use `will-change: transform` to hint—but creates layer, uses memory
- Don't overuse `will-change`—hundreds of layers = memory issues
- `transform: translateZ(0)` to force layer—but prefer `will-change`

## Layout Thrashing

- Reading layout property forces synchronous layout—batch reads together
- Write all changes, then read if needed—don't interleave
- Use `requestAnimationFrame` for visual changes—batches with next frame
- Virtual DOM frameworks handle this—but still know the concept

## Selector Performance

- Right-to-left matching—browser finds all matches of rightmost, filters up
- Qualified selectors slower—`div.class` slower than `.class`
- Deep nesting expensive—`.a .b .c .d .e` searches a lot
- ID selectors fastest but least reusable

## Font Loading

- FOUT (Flash of Unstyled Text) with `font-display: swap`—shows fallback first
- FOIT (Flash of Invisible Text) with `block`—text hidden until loaded
- `font-display: optional` best for performance—may not show custom font
- Preload critical fonts: `<link rel="preload" as="font" crossorigin>`

## CSS File Optimization

- Unused CSS still downloaded and parsed—audit and remove
- `@import` is render-blocking—use `<link>` tags instead
- Critical CSS inline in `<head>`—rest can load async
- Consider CSS-in-JS tradeoffs—runtime cost vs HTTP cache

## Paint Optimization

- `box-shadow` on scroll elements is expensive—moves repaint on scroll
- Large `border-radius` with overflow can be costly
- `filter: blur()` on large elements expensive
- Use compositor-only properties when possible

## Measuring Performance

- Chrome DevTools Performance panel—see paint, layout, script timing
- "Show paint rectangles"—visualize what's being repainted
- Lighthouse for overall audit—catches common issues
- Test on real low-end devices—your MacBook is not representative


path: responsive.md
content: # Responsive Techniques

## Viewport Units Traps

- `100vh` on mobile includes toolbar—content behind address bar
- `100dvh` (dynamic viewport) changes as toolbar hides/shows—causes reflow
- `100svh` (small viewport) always excludes toolbar—most predictable
- Mix: `height: 100svh; min-height: 100dvh` for hero sections

## Media Query Patterns

- Mobile-first: use `min-width`—base styles for mobile, layer up for larger
- `min-width` is mobile-first; `max-width` is desktop-first—don't mix approaches
- Common breakpoints: 640px, 768px, 1024px, 1280px—but adapt to your content
- Prefer intrinsic sizing over breakpoints—fewer media queries needed

## Container Queries

- `container-type: inline-size` on parent—enables queries on that container
- `@container (min-width: 400px) { ... }`—component responds to ITS container
- `container-name` for targeting specific ancestor—`@container sidebar (min-width: ...)`
- Better than media queries for reusable components—same component, different contexts

## Fluid Typography

- `clamp(min, preferred, max)` for smooth scaling—`font-size: clamp(1rem, 2vw + 0.5rem, 2rem)`
- Don't use only vw—user can't resize text, accessibility issue
- Always include rem component—`2vw + 0.5rem` allows zoom to work
- Test at extreme widths—very wide screens can make huge text

## Fluid Spacing

- `clamp()` for padding/margin too—`padding: clamp(1rem, 5vw, 3rem)`
- CSS `min()` and `max()` for one-sided constraints—`width: min(100%, 800px)`
- Combine with calc: `calc(1rem + 2vw)`—smooth transition between sizes
- Use CSS custom properties for consistent fluid scales

## Image Responsiveness

- `max-width: 100%; height: auto` on images—prevents overflow, maintains ratio
- `object-fit: cover` vs `contain`: cover crops, contain letterboxes
- `aspect-ratio` on container holds space—prevents layout shift during load
- `srcset` and `sizes` for art direction—browser picks best image

## Layout Shifts

- Reserve space for images—use `aspect-ratio` or explicit dimensions
- Font loading causes shift—use `font-display: swap` or preload critical fonts
- Ads/embeds shift content—reserve space with `min-height`
- `scrollbar-gutter: stable`—prevents shift when scrollbar appears/disappears

## Testing Responsive

- Test on real devices—emulators miss real performance and touch targets
- Test with real content—long words, missing images, user-generated text
- Test both orientations—landscape tablet is not the same as desktop
- Check over-scroll behavior—pull-to-refresh, bounce effects


path: selectors.md
content: # Selectors and Specificity

## Specificity Rules

- Inline styles: 1000, ID: 100, Class: 10, Element: 1—cumulative
- `:where()` has ZERO specificity—great for defaults that are easy to override
- `:is()` takes HIGHEST specificity of its arguments—can surprise you
- `!important` beats all—but avoid in component styles, breaks cascade

## Modern Selector Patterns

- `:is(h1, h2, h3)` for grouping—less repetition than commas
- `:where(.btn, .link):hover` for low-specificity shared styles
- `:has(.error)` parent selector—style parent based on child
- `:focus-visible` instead of `:focus`—keyboard only, no outline on click

## :has() Patterns

- `.card:has(img)` style card based on contents—true parent selector
- `form:has(:invalid)` style form when any input invalid
- `.item:has(+ .active)` select item BEFORE active—previous sibling
- Performance cost—use sparingly on large documents

## Pseudo-class Traps

- `:nth-child` vs `:nth-of-type`—child counts all siblings, type only same element
- `:first-child` inside wrapper—first child of wrapper, not first matching element
- `:empty` is strict—whitespace text nodes count as content, element not empty
- `:not()` doesn't add specificity in old syntax—does in modern syntax with complex selectors

## Pseudo-element Patterns

- `::before`/`::after` need `content: ""`—empty string at minimum
- Can't add pseudo-elements to `<img>`, `<input>`—replaced elements
- Double colon `::` is CSS3—single `:` still works but deprecated
- `::placeholder` for input placeholders—needs vendor prefixes in older browsers

## Attribute Selectors

- `[disabled]` has attribute—regardless of value
- `[href^="https"]` starts with—external links
- `[href$=".pdf"]` ends with—PDF downloads
- `[data-state="active" i]` case-insensitive match—the `i` flag

## Combinator Performance

- Browser matches selectors right-to-left—`.nav li a` finds all `a`, then filters
- Deep descendant selectors can be slow—`.a .b .c .d .e` is expensive
- Direct child `>` is more efficient—limits search scope
- ID selectors are fastest—but poor for reusable components

## Specificity Management

- Use BEM or similar—keeps specificity flat and predictable
- Layer: reset, base, components, utilities—utilities can override
- CSS custom properties ignore specificity—great for theming
- Use `@layer` for explicit cascade ordering—modern approach


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)