home / skills / sergiodxa / agent-skills / frontend-tailwind-best-practices

frontend-tailwind-best-practices skill

/skills/frontend-tailwind-best-practices

This skill helps you apply Tailwind best practices for layout, color schemes, and className handling to speed frontend development.

npx playbooks add skill sergiodxa/agent-skills --skill frontend-tailwind-best-practices

Review the files below or copy the command above to add this skill to your agents.

Files (11)
SKILL.md
5.2 KB
---
name: frontend-tailwind-best-practices
description: Tailwind CSS patterns and conventions for frontend apps. Use when writing component styles, layouts, or working with CSS classes.
---

# Tailwind CSS Best Practices

Styling patterns and conventions for frontend applications. Contains 10 rules covering layout utilities, affordances, color schemes, responsive design, and className handling.

## When to Apply

Reference these guidelines when:

- Writing component styles with Tailwind
- Creating layouts (stacks, grids, centering)
- Handling responsive design
- Working with color schemes
- Merging className props

## Rules Summary

### Layout Utilities (CRITICAL)

#### layout-stack-utilities - @rules/layout-stack-utilities.md

Use custom stack utilities instead of flex classes.

```tsx
// Bad
<div className="flex flex-col gap-4">
<div className="flex flex-row gap-4">

// Good
<div className="v-stack gap-4">
<div className="h-stack gap-4">
```

Available utilities:

- `v-stack` - Vertical stack (flex column)
- `h-stack` - Horizontal stack (flex row)
- `v-stack-reverse` - Reversed vertical stack
- `h-stack-reverse` - Reversed horizontal stack
- `z-stack` - Overlapping stack (grid-based, centers children on top of each other)
- `center` - Center content both horizontally and vertically
- `spacer` - Flexible spacer that fills available space
- `circle` - Perfect circle with aspect-ratio 1/1

#### layout-prefer-gaps - @rules/layout-prefer-gaps.md

Use `gap-*` on parents instead of child margins.

```tsx
// Bad
<div>
  <Item className="mb-4" />
  <Item className="mb-4" />
</div>

// Good
<div className="flex flex-col gap-4">
  <Item />
  <Item />
</div>
```

#### layout-responsive-stacks - @rules/layout-responsive-stacks.md

Switch layout direction at breakpoints.

```tsx
// Mobile: vertical, Desktop: horizontal
<div className="v-stack lg:h-stack gap-4">
  <main className="grow">...</main>
  <aside className="shrink-0 lg:w-80">...</aside>
</div>

// Mobile: horizontal, Desktop: vertical
<div className="h-stack md:v-stack">
```

### Color Schemes (CRITICAL)

#### color-schemes - @rules/color-schemes.md

Use class-based color schemes with a custom `dark` variant.

```tsx
<button className="rounded-full bg-gray-900 px-4 py-2 text-white dark:bg-gray-100 dark:text-gray-900">
  Toggle
</button>
```

### className Handling (CRITICAL)

#### classname-cn-utility - @rules/classname-cn-utility.md

Always use `cn()` to merge classNames in components.

```tsx
import { cn } from "~/lib/cn";

function Button({ className, variant }: Props) {
  return (
    <button
      className={cn(
        "base-classes",
        {
          "variant-primary": variant === "primary",
          "variant-secondary": variant === "secondary",
        },
        className, // external className always last
      )}
    />
  );
}
```

#### classname-prop-types - @rules/classname-prop-types.md

Use proper types for className props.

```tsx
import type { ClassName, ClassNameRecord } from "~/lib/cn";

// Single element
type Props = {
  className?: ClassName;
};

// Multiple elements
type Props = {
  className?: ClassNameRecord<"root" | "label" | "input">;
};

// Usage
<Input className={{ root: "w-full", label: "font-bold" }} />;
```

### Affordances (HIGH)

#### affordance-classes - @rules/affordance-classes.md

Define element-agnostic visual patterns that compose with utilities.

```tsx
<label className="ui-button" htmlFor="document-upload">
  Choose file
</label>
```

### Responsive Design (MEDIUM)

#### responsive-breakpoints - @rules/responsive-breakpoints.md

Use responsive prefixes with Tailwind defaults.

```tsx
// Standard breakpoints (min-width)
<div className="px-4 md:px-8 lg:px-12">

// Show/hide with standard breakpoints
<div className="hidden md:block">Desktop only</div>
<div className="md:hidden">Mobile only</div>
```

#### responsive-text - @rules/responsive-text.md

Scale text responsively.

```tsx
// Responsive font size
<h1 className="text-2xl md:text-3xl lg:text-4xl">

// Responsive line height with text
<p className="text-sm leading-5 md:text-base md:leading-6">
```

#### responsive-capabilities - @rules/responsive-capabilities.md

Design for input capabilities (pointer/hover) instead of device labels.

```tsx
<button className="h-10 w-10 pointer-coarse:h-12 pointer-coarse:w-12">
  <Icon />
</button>
```

## Anti-Patterns

| Don't                              | Do                     |
| ---------------------------------- | ---------------------- |
| `flex flex-col`                    | `v-stack`              |
| `flex flex-row`                    | `h-stack`              |
| `flex items-center justify-center` | `center`               |
| `bg-gray-100`                      | `bg-neutral-100`       |
| `bg-[#hex]`                        | Use design tokens      |
| `className="..."` without `cn()`   | `cn("...", className)` |
| Inline `style` for responsive      | Tailwind prefixes      |

## Key Files

| File                      | Purpose                          |
| ------------------------- | -------------------------------- |
| `tailwind.config.js`      | Config, custom utilities, colors |
| `app/styles/global.css`   | Color scheme CSS variables       |
| `app/styles/tailwind.css` | Additional utilities             |
| `app/utils/cn.ts`         | className merge utility          |

Overview

This skill documents Tailwind CSS patterns and conventions for frontend applications. It focuses on reusable layout utilities, color schemes, responsive behavior, and safe className handling. Use it to standardize component styling and reduce CSS duplication across projects.

How this skill works

The guidance defines a small set of custom utilities (v-stack, h-stack, center, spacer, circle, z-stack) to replace repetitive flex/grid patterns and encourage gap-based spacing. It prescribes class-based dark mode color schemes, responsive prefixes for typography and layout, and a cn() utility for deterministic className merging and typing. Anti-patterns and concrete examples show preferred replacements for common mistakes.

When to use it

  • When writing component styles and composing layout primitives.
  • When creating responsive stacks, grids, or center-aligned layouts.
  • When implementing light/dark color schemes using classes.
  • When merging external className props in components.
  • When scaling typography and spacing across breakpoints.

Best practices

  • Prefer custom stack utilities (v-stack/h-stack) over raw flex classes for clarity.
  • Use parent gap utilities instead of child margins to manage spacing.
  • Always merge classes with a cn() utility and type className props for safety.
  • Use class-based color schemes with a dark variant and design tokens, avoid hex literals.
  • Design responsive rules around capabilities (pointer/hover) and standard breakpoints.

Example use cases

  • A card list using v-stack gap utilities instead of individual margins between items.
  • A responsive layout that switches from v-stack on mobile to h-stack on desktop with lg: prefixes.
  • A button component that uses cn() to combine base classes, variant classes, and external className prop.
  • Implementing dark mode by adding dark:bg-... and dark:text-... classes to components.
  • Sizing touch targets using pointer-coarse: utilities for improved tap accessibility.

FAQ

Why use custom stack utilities instead of flex classes?

They provide a semantic, consistent shorthand (v-stack/h-stack) that reduces repetition and makes intent clearer across components.

What does cn() solve?

cn() deterministically merges static, conditional, and external className values and lets you define safe prop types for single or multiple element className objects.