1---2name: tailwind-css3description: Write Tailwind utility classes with proper responsive design, dark mode, and configuration.4---5
6## Content Configuration
7
8- `content` array in tailwind.config.js must include ALL files with classes—missing paths = missing styles in production
9- Glob patterns: `"./src/**/*.{js,jsx,ts,tsx,html}"` covers nested directories
10- Dynamic class names like `bg-${color}-500` won't be detected—use complete class names or safelist
11- Check production build size—if unexpectedly small, content paths are wrong
12
13## Responsive Prefixes
14
15- Mobile-first: unprefixed styles apply to all sizes, `md:` applies at medium AND above
16- `sm:hidden md:block` means hidden on small, visible on medium+—not "only on medium"
17- Breakpoints: sm(640px), md(768px), lg(1024px), xl(1280px), 2xl(1536px)
18- Custom breakpoints in config override defaults—use `extend.screens` to add without replacing
19
20## Dark Mode
21
22- `dark:` prefix requires `darkMode: 'class'` in config—won't work with default media strategy if you need manual toggle
23- Dark class on `<html>` or `<body>`, not on individual components
24- `dark:bg-gray-900` only applies when ancestor has `class="dark"`
25- System preference: `darkMode: 'media'` uses `prefers-color-scheme`
26
27## State Variants
28
29- `hover:`, `focus:`, `active:` work as expected
30- `group-hover:` requires `group` class on parent—child reacts to parent hover
31- `peer-focus:` requires `peer` class on sibling AND sibling must come first in DOM
32- Stack variants: `dark:hover:bg-gray-700` applies on hover in dark mode
33
34## Arbitrary Values
35
36- `bg-[#1da1f2]` for one-off colors—brackets for any arbitrary value
37- `w-[calc(100%-2rem)]` for calc expressions
38- `grid-cols-[1fr_2fr_1fr]` underscores for spaces in values
39- Arbitrary properties: `[mask-type:alpha]` for unsupported CSS properties
40
41## @apply Traps
42
43- `@apply` in component CSS loses responsive/state variants—`@apply hover:bg-blue-500` doesn't work as expected
44- Order in `@apply` matters unlike HTML classes—later utilities override earlier
45- Prefer HTML classes over `@apply`—easier to maintain, better tree-shaking
46- If you must use `@apply`, keep it simple: base styles only
47
48## Configuration
49
50- `extend` adds to defaults: `extend: { colors: { brand: '#xxx' } }` keeps all existing colors
51- Top-level replaces defaults: `colors: { brand: '#xxx' }` removes all default colors
52- `theme()` function in CSS: `border-color: theme('colors.gray.200')`
53- Plugin order matters—later plugins can override earlier ones
54
55## Important Modifier
56
57- `!` prefix forces important: `!mt-4` generates `margin-top: 1rem !important`
58- Use sparingly—usually indicates specificity battle that should be fixed
59- `important: true` in config makes ALL utilities important—avoid, breaks third-party CSS
60- `important: '#app'` scopes specificity to selector—better than global important
61
62## Common Mistakes
63
64- `class="px-4 px-6"` last one wins in stylesheet, not in HTML—both get applied, cascade decides
65- Forgetting `overflow-hidden` with `rounded-*` on parent with absolute children
66- `h-screen` doesn't account for mobile browser chrome—use `h-dvh` (dynamic viewport height)
67- `truncate` needs width constraint or `max-w-*` to actually truncate
68
69## Performance
70
71- JIT is default since v3—generates only used classes, no purge needed
72- Avoid `safelist` with patterns like `bg-*`—defeats tree-shaking
73- `@layer components` for reusable component styles—proper cascade order
74- Large arbitrary values generate unique classes—extract to config if repeated