# CSS Skill

> This skill should be used when the user asks about CSS, CSS selectors, specificity, cascade, inheritance, Flexbox, CSS Grid, CSS custom properties (variables), animations, transitions, transforms, media queries, container queries, CSS pseudo-classes, pseudo-elements, CSS functions (calc, clamp, min, max), CSS architecture (BEM, SMACSS), CSS preprocessors (Sass/SCSS), CSS-in-JS, CSS modules, @layer, @scope, logical properties, scroll-driven animations, or any CSS styling topic. Trigger when the user mentions "css", "flexbox", "css grid", "css variables", "custom properties", "media query", "container query", "css animation", "keyframes", "css transition", "css selector", "specificity", "sass", "scss", "css modules", "bem", "clamp()", "aspect-ratio", "css grid layout", "nth-child", "pseudo-class", "pseudo-element", or asks how to style something with CSS.

- Skill: `sirhamza/css-skill` (Agent Skill)
- Install (CLI): `npx skillmds@latest add sirhamza/css-skill`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sirhamza/css-skill/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: SirHamza (https://skillmd.com/u/sirhamza)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/sirhamza/css-skill

---


# CSS Expert

## Overview

Advanced expertise in CSS — from the cascade, specificity, and layout fundamentals (Flexbox, Grid) to modern CSS features (cascade layers, container queries, scroll animations, `@scope`), architecture patterns, and Sass/SCSS.

---

## 1. The Cascade, Specificity & Inheritance

### Cascade Order (high → low priority)
1. `!important` + inline styles
2. `!important` + ID selectors
3. `!important` + class/attribute/pseudo-class
4. `!important` + type/pseudo-element
5. Inline styles (`style=""`)
6. ID selectors (`#id`)
7. Class / attribute / pseudo-class (`.class`, `[attr]`, `:hover`)
8. Type / pseudo-element (`div`, `::before`)
9. Universal selector (`*`), combinators
10. Inherited values
11. Browser defaults

### Specificity Calculation
```
(a, b, c)
a = number of ID selectors
b = number of class, attribute, pseudo-class selectors
c = number of type, pseudo-element selectors

#nav .item:hover    → (1, 2, 0)
.card > p           → (0, 1, 1)
div ul li.active    → (0, 1, 3)
:where(.card)       → (0, 0, 0)  always zero specificity
:is(.card, #hero)   → takes highest specificity of its args
```

### Inheritance
```css
/* Inherited by default: color, font-*, line-height, text-*, visibility, cursor */
/* Not inherited: margin, padding, border, background, display, width, height */

p { color: inherit; }      /* force inheritance */
p { color: initial; }      /* reset to browser default */
p { color: unset; }        /* inherits if inheritable, else initial */
p { color: revert; }       /* revert to browser/user stylesheet */
p { all: unset; }          /* reset all properties */
```

---

## 2. Selectors

```css
/* Combinators */
div p          /* descendant */
div > p        /* direct child */
h1 + p         /* adjacent sibling */
h1 ~ p         /* general sibling */

/* Attribute selectors */
[type="text"]           /* exact match */
[class~="card"]         /* space-separated word match */
[href^="https"]         /* starts with */
[href$=".pdf"]          /* ends with */
[href*="example"]       /* contains */
[lang|="en"]            /* exact or starts with "en-" */

/* Pseudo-classes */
:hover  :focus  :active  :visited  :link
:focus-visible          /* keyboard focus only (not mouse click) */
:focus-within           /* has focused descendant */
:checked  :disabled  :enabled  :required  :optional
:valid  :invalid  :placeholder-shown  :user-valid  :user-invalid
:empty                  /* no children or text */
:target                 /* element whose id matches URL hash */
:root                   /* <html> — highest specificity for custom props */

/* Structural pseudo-classes */
:first-child   :last-child   :only-child
:nth-child(2)           /* 2nd child */
:nth-child(2n)          /* even children */
:nth-child(2n+1)        /* odd children */
:nth-child(3n+1)        /* every 3rd starting at 1 */
:nth-child(n+3)         /* 3rd and beyond */
:nth-child(-n+3)        /* first 3 */
:nth-of-type(2)         /* 2nd of its element type */
:not(.excluded)         /* negation */
:not(h1, h2, h3)       /* multiple args (Selectors 4) */
:is(h1, h2, h3) span   /* matches any heading's span */
:where(.card, .box)     /* like :is() but zero specificity */
:has(> img)             /* parent has direct child img */
:has(+ .sibling)        /* element followed by .sibling */

/* Pseudo-elements */
::before  ::after       /* generated content */
::placeholder
::selection
::first-line  ::first-letter
::marker                /* list item bullet */
::backdrop              /* behind <dialog> */
::file-selector-button
```

---

## 3. Flexbox

```css
/* Container */
.flex {
  display: flex;                /* or inline-flex */
  flex-direction: row;          /* row | row-reverse | column | column-reverse */
  flex-wrap: nowrap;            /* nowrap | wrap | wrap-reverse */
  flex-flow: row wrap;          /* shorthand */

  /* Main axis alignment */
  justify-content: flex-start;  /* flex-start | flex-end | center | space-between | space-around | space-evenly */

  /* Cross axis alignment */
  align-items: stretch;         /* stretch | flex-start | flex-end | center | baseline */

  /* Multi-line cross axis */
  align-content: normal;        /* same values as justify-content */

  gap: 16px;                    /* row-gap + column-gap */
  gap: 16px 24px;               /* row-gap column-gap */
}

/* Items */
.item {
  flex-grow: 0;                 /* proportion of free space to take */
  flex-shrink: 1;               /* ability to shrink */
  flex-basis: auto;             /* initial size before grow/shrink */
  flex: 1;                      /* flex: 1 1 0 */
  flex: 1 1 auto;               /* grow, shrink, auto basis */
  flex: 0 0 200px;              /* fixed 200px, no grow/shrink */

  align-self: auto;             /* override align-items for this item */
  order: 0;                     /* visual reorder */
  margin-left: auto;            /* push item to far right */
}

/* Common patterns */
/* Center anything */
.center { display: flex; align-items: center; justify-content: center; }

/* Sticky footer */
.page { display: flex; flex-direction: column; min-height: 100vh; }
.main { flex: 1; }

/* Equal-width columns */
.cols > * { flex: 1; }

/* Auto-wrap responsive grid */
.grid { display: flex; flex-wrap: wrap; gap: 1rem; }
.grid > * { flex: 1 1 min(300px, 100%); }
```

---

## 4. CSS Grid

```css
/* Container */
.grid {
  display: grid;                /* or inline-grid */

  /* Define columns */
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-columns: repeat(3, 1fr);
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));  /* responsive */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));   /* collapse empty */
  grid-template-columns: 200px 1fr;                               /* sidebar + main */
  grid-template-columns: [sidebar-start] 240px [sidebar-end main-start] 1fr [main-end];

  /* Define rows */
  grid-template-rows: auto 1fr auto;  /* header, main, footer */
  grid-auto-rows: minmax(100px, auto); /* implicit row size */
  grid-auto-flow: row dense;  /* fill gaps with dense packing */

  /* Gap */
  gap: 24px;
  gap: 16px 24px;           /* row-gap column-gap */

  /* Named areas */
  grid-template-areas:
    "header header header"
    "sidebar main    main"
    "footer  footer  footer";

  /* Alignment */
  justify-items: stretch;   /* align cells on inline axis */
  align-items: stretch;     /* align cells on block axis */
  justify-content: start;   /* align grid on inline axis */
  align-content: start;     /* align grid on block axis */
  place-items: center;      /* align-items + justify-items */
  place-content: center;    /* align-content + justify-content */
}

/* Items */
.item {
  grid-column: 1 / 3;          /* start / end line */
  grid-column: 1 / span 2;     /* start / span count */
  grid-column: sidebar-start / sidebar-end;  /* named lines */
  grid-row: 2 / 4;

  grid-area: header;            /* assign to named area */
  grid-area: 1 / 1 / 2 / 3;   /* row-start / col-start / row-end / col-end */

  justify-self: center;         /* override justify-items */
  align-self: end;              /* override align-items */
  place-self: center end;
}

/* Holy Grail Layout */
.page {
  display: grid;
  grid-template: "header" auto "sidebar main" 1fr "footer" auto / 200px 1fr;
  min-height: 100vh;
}
header { grid-area: header; }
aside  { grid-area: sidebar; }
main   { grid-area: main; }
footer { grid-area: footer; }
```

---

## 5. CSS Custom Properties (Variables)

```css
/* Define */
:root {
  --color-primary: #3b82f6;
  --color-primary-dark: #1d4ed8;
  --spacing-md: 1rem;
  --radius: 0.5rem;
  --font-sans: 'Inter', sans-serif;
  --shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}

/* Use */
.button {
  background: var(--color-primary);
  padding: var(--spacing-md);
  border-radius: var(--radius);
  /* Fallback value */
  color: var(--button-color, white);
}

/* Scoped variables */
.card {
  --card-padding: 1.5rem;
  padding: var(--card-padding);
}

/* Dark mode via variables */
:root { --bg: #ffffff; --text: #111827; }
.dark { --bg: #111827; --text: #f9fafb; }
@media (prefers-color-scheme: dark) {
  :root { --bg: #111827; --text: #f9fafb; }
}

/* Computed / dynamic */
.progress {
  --value: 70;
  width: calc(var(--value) * 1%);
}
```

---

## 6. Responsive Design — Media & Container Queries

```css
/* Media Queries */
@media (max-width: 768px) { }              /* mobile */
@media (min-width: 768px) { }              /* tablet+ (mobile-first) */
@media (min-width: 768px) and (max-width: 1024px) { }
@media (prefers-color-scheme: dark) { }
@media (prefers-reduced-motion: reduce) { }
@media (prefers-contrast: high) { }
@media print { }
@media (hover: hover) and (pointer: fine) { } /* mouse device */
@media (hover: none) { }                    /* touch device */
@media (orientation: landscape) { }
@media (display-mode: standalone) { }       /* PWA installed */

/* Container Queries (modern — target parent size, not viewport) */
.card-wrapper {
  container-type: inline-size;
  container-name: card;
}
@container card (min-width: 400px) {
  .card { flex-direction: row; }
}
@container (min-width: 600px) {
  .card__title { font-size: 1.5rem; }
}

/* Style Queries */
@container style(--variant: compact) {
  .card { padding: 0.5rem; }
}

/* Responsive type with clamp() */
h1 { font-size: clamp(1.5rem, 4vw + 1rem, 3rem); }
p  { font-size: clamp(1rem, 1.5vw, 1.25rem); }

/* Fluid spacing */
.section { padding: clamp(2rem, 5vw, 5rem); }
```

---

## 7. CSS Functions

```css
/* Math functions */
width: calc(100% - 2rem);
width: calc(var(--sidebar) + 48px);
width: min(100%, 800px);      /* smallest value */
width: max(300px, 50%);       /* largest value */
width: clamp(200px, 50%, 800px); /* min, preferred, max */

/* Color functions */
color: rgb(59 130 246);                    /* modern no-comma syntax */
color: rgb(59 130 246 / 0.5);             /* with alpha */
color: hsl(217 91% 60%);
color: hsl(217 91% 60% / 0.8);
color: color-mix(in oklch, #3b82f6 80%, white);   /* blend colors */
color: oklch(0.6 0.2 240);               /* perceptually uniform */
color: light-dark(#fff, #000);           /* automatic light/dark */

/* Transform functions */
transform: translate(10px, 20px) rotate(45deg) scale(1.2);
transform: translateX(50%) translateY(-50%);  /* center absolute element */

/* Gradient */
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
background: radial-gradient(circle at center, #3b82f6, transparent);
background: conic-gradient(from 90deg, red, yellow, green, blue, red);

/* Shapes */
clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
clip-path: circle(50%);
clip-path: inset(0 0 20% 0 round 8px);
shape-outside: circle(50%);

/* Other */
filter: blur(4px) brightness(0.8) contrast(1.2) grayscale(100%);
backdrop-filter: blur(10px) saturate(180%);
content: counter(section) ". ";
```

---

## 8. Animations & Transitions

```css
/* Transitions */
.btn {
  transition: background-color 200ms ease, transform 150ms ease, box-shadow 200ms ease;
  /* property duration timing-function delay */
}
.btn:hover {
  background-color: #1d4ed8;
  transform: translateY(-2px);
  box-shadow: 0 10px 20px rgb(0 0 0 / 0.15);
}

/* Keyframe animations */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.5; }
}

.element {
  animation: fadeIn 400ms ease-out both;
  /* name duration timing fill-mode */
  animation: spin 1s linear infinite;
  animation-delay: 200ms;
  animation-play-state: paused;  /* or running */
  animation-iteration-count: 3;
}

/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* Scroll-driven animations (Chrome 115+) */
@keyframes reveal {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}
.reveal {
  animation: reveal linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 30%;
}

/* View transitions */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 300ms ease out slide-out; }
::view-transition-new(root) { animation: 300ms ease in slide-in; }
```

---

## 9. Cascade Layers (`@layer`)

```css
/* Declare order (lower = lower priority) */
@layer reset, base, components, utilities;

@layer reset {
  *, *::before, *::after { box-sizing: border-box; margin: 0; }
}

@layer base {
  body { font-family: var(--font-sans); color: var(--color-text); }
  a { color: var(--color-primary); }
}

@layer components {
  .btn { /* component styles */ }
  .card { /* card styles */ }
}

@layer utilities {
  .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
  .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* Styles outside any layer beat all layered styles */
.override { color: red; }   /* always wins vs layered styles */

/* Import with layer */
@import url("reset.css") layer(reset);
```

---

## 10. Sass / SCSS

```scss
// Variables
$color-primary: #3b82f6;
$spacing-base: 1rem;
$breakpoint-md: 768px;

// Nesting
.card {
  background: white;
  padding: $spacing-base;

  &__title { font-size: 1.25rem; }   // BEM modifier
  &--featured { border: 2px solid $color-primary; }

  &:hover { box-shadow: 0 4px 12px rgb(0 0 0 / 0.1); }

  @media (min-width: $breakpoint-md) {
    padding: $spacing-base * 1.5;
  }
}

// Mixins
@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

@mixin responsive($breakpoint) {
  @if $breakpoint == md { @media (min-width: 768px) { @content; } }
  @if $breakpoint == lg { @media (min-width: 1024px) { @content; } }
}

.hero {
  @include flex-center;
  @include responsive(md) { padding: 4rem; }
}

// Functions
@function rem($px) { @return ($px / 16) * 1rem; }
.element { font-size: rem(18); }

// Extend / Placeholder
%visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0,0,0,0);
}
.sr-only { @extend %visually-hidden; }

// Loops
@each $size in sm, md, lg {
  .gap-#{$size} { gap: map-get((sm: 0.5rem, md: 1rem, lg: 2rem), $size); }
}

@for $i from 1 through 12 {
  .col-#{$i} { width: ($i / 12 * 100%); }
}
```

---

## 11. CSS Architecture — BEM

```css
/* Block__Element--Modifier */
.card { }                          /* Block */
.card__title { }                   /* Element */
.card__body { }                    /* Element */
.card__image { }                   /* Element */
.card--featured { }                /* Modifier */
.card--compact { }                 /* Modifier */
.card__title--large { }            /* Element + Modifier */

/* Never: .card .title (descendant — breaks encapsulation) */
/* Always: .card__title (flat BEM selector) */
```

---

## 12. Modern CSS Snippets

```css
/* Smooth scroll */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Custom scroll bar */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: #f1f5f9; }
::-webkit-scrollbar-thumb { background: #94a3b8; border-radius: 4px; }
scrollbar-width: thin; scrollbar-color: #94a3b8 #f1f5f9; /* Firefox */

/* Aspect ratio */
.video { aspect-ratio: 16 / 9; width: 100%; }
.avatar { aspect-ratio: 1; }

/* Text clamp */
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* Logical properties (LTR/RTL aware) */
.box {
  margin-inline: auto;           /* = margin-left + margin-right */
  padding-block: 1rem;           /* = padding-top + padding-bottom */
  border-inline-start: 4px solid blue; /* = border-left in LTR */
  inset-inline-start: 0;        /* = left in LTR */
}

/* Subgrid */
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
.card { grid-column: span 3; display: grid; grid-template-columns: subgrid; }

/* :has() real-world uses */
.form-group:has(:invalid) label { color: red; }
nav:has(.dropdown:hover) { z-index: 100; }
main:has(> aside) { grid-template-columns: 1fr 300px; }

/* CSS Nesting (native, no Sass needed) */
.card {
  color: black;
  & .title { font-size: 1.25rem; }
  &:hover { background: #f9fafb; }
  @media (min-width: 768px) { padding: 2rem; }
}
```

---

## Core Competency Summary

- Master the cascade, specificity, and inheritance to write predictable CSS
- Build complex layouts with Flexbox and CSS Grid (named areas, subgrid, auto-fill/auto-fit)
- Use CSS custom properties for themeable, maintainable design systems
- Write responsive designs with media queries and container queries
- Create smooth animations and transitions, respecting `prefers-reduced-motion`
- Leverage modern CSS: `@layer`, `@scope`, `:has()`, `clamp()`, `color-mix()`, scroll-driven animations
- Architect scalable stylesheets with BEM naming and Sass/SCSS

