Tailwind
Skill mickzijdel/dev-hooks/plugins/dev-hooks/skills/tailwind
Hooks and skills for Claude to write better code and verify its work, and an easy start to using Claude Code
npx -y skills add mickzijdel/dev-hooks --skill tailwindAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when writing or fixing Tailwind CSS — in HTML, ERB/ViewComponent, JSX, Vue, or any template that carries utility classes. Covers design tokens, taming class soup, component-first extraction, dark mode, responsive layout, and accessibility. Triggers on "tailwind", "css", "styling", "dark mode", "responsive", "class soup", "@apply", "design system", or any "make this look right / fix this layout" request — even when styling isn't named explicitly, since templates almost always contain Tailwind classes.
SKILL.md
10.1 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
Tailwind CSS
Tailwind works well at scale only with two things in place: a design system of consistent tokens and a component-based architecture. Most Tailwind pain — unreadable class soup, inconsistent spacing, forgotten dark mode — traces back to missing one of them. This skill enforces both, plus dark mode, responsive, and accessibility as defaults rather than afterthoughts.
Tailwind styles; it does not position floating UI. For dropdowns, tooltips, and popovers that must stay on-screen, see the companion popovers-tooltips skill.
The golden rules
- No plain CSS. Style through Tailwind utilities, or
@applyinside a component layer. Don't hand-write raw CSS properties. - No inline styles. Never use the
styleattribute. If Tailwind lacks a utility, extend the config. - Reuse components first. Before adding classes to a new element, check whether an existing partial, component, or shared pattern already handles it.
- Design tokens over magic numbers. Use the colors, spacing, and sizes from your config — not arbitrary values like
bg-[#3b82f6]orp-[13px]. - Every UI works in light and dark mode. No exceptions.
- Every UI is responsive. No exceptions.
Design system: theme configuration
The single source of truth for visual decisions is the Tailwind theme (tailwind.config.js, or
@theme in CSS for Tailwind v4). Colors, spacing, and breakpoints come from there — not from
arbitrary values scattered across templates.
Name colors by purpose, not appearance
Semantic names let you restyle the palette without hunting through every template:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: { /* … */ }, // brand / main actions
secondary: { /* … */ }, // supporting actions
accent: { /* … */ }, // highlights and emphasis
success: { /* … */ }, // positive feedback
warning: { /* … */ }, // cautionary feedback
error: { /* … */ }, // error states
surface: { /* … */ }, // backgrounds and cards
muted: { /* … */ }, // subdued text and borders
}
}
}
}
Use bg-primary-500, text-error-600, border-muted-200 in templates. Never raw hex or arbitrary color values.
Stick to one spacing scale
Tailwind's default scale (0, 1, 2, 3, 4, 5, 6, 8, 10, 12, …) is solid. Extend it only with a clear reason — and when you do, add a token rather than reaching for arbitrary values:
<!-- WRONG — arbitrary spacing breaks visual rhythm -->
<div class="p-[13px] mt-[7px] gap-[22px]">
<!-- RIGHT — use the scale -->
<div class="p-3 mt-2 gap-5">
Reducing class bloat
Long utility strings — "class soup" — make templates hard to read. Keep class lists short, scannable, intentional.
Use shorthand utilities instead of spelling out each direction:
<!-- WRONG --> <div class="pt-4 pb-4 pl-6 pr-6">
<!-- RIGHT --> <div class="py-4 px-6">
Drop classes that duplicate defaults:
<!-- WRONG — flex-row is the default --> <div class="flex flex-row justify-between">
<!-- RIGHT --> <div class="flex justify-between">
Keep class order consistent so classes are predictable to scan —
layout → sizing → spacing → typography → colors → effects → states. Automate it with the official
prettier-plugin-tailwindcss rather than ordering by hand:
// .prettierrc
{ "plugins": ["prettier-plugin-tailwindcss"] }
Component-first architecture
The primary weapon against class soup is extracting a component, not @apply. When the same
cluster of classes repeats across templates, extract it into a partial or component — not a CSS
abstraction.
<%# WRONG — the same button classes copy-pasted everywhere %>
<button class="inline-flex items-center gap-2 px-4 py-2 bg-primary-500 text-white rounded-lg hover:bg-primary-600 dark:bg-primary-600 dark:hover:bg-primary-700">
Save
</button>
<%# RIGHT — extract a component, pass a variant %>
<%= render ButtonComponent.new(variant: :primary, label: "Save") %>
Use a finite set of variants rather than accepting arbitrary classes — this keeps the design system consistent and gives you one place to edit:
# app/components/button_component.rb
VARIANTS = {
primary: "bg-primary-500 text-white hover:bg-primary-600 dark:bg-primary-600 dark:hover:bg-primary-700",
secondary: "bg-surface-100 text-surface-800 hover:bg-surface-200 dark:bg-surface-700 dark:text-surface-100",
danger: "bg-error-500 text-white hover:bg-error-600 dark:bg-error-600 dark:hover:bg-error-700"
}.freeze
Changing a variant propagates everywhere it's used — one edit, not dozens. (In a Rails app, the
component owns its class map in a constant — see the rails-toolkit rails-viewcomponents skill.)
When to reach for @apply
Reserve @apply for cases where component extraction isn't practical — global base styles,
third-party overrides, or markup generated by libraries you don't control. Keep it inside
@layer components to avoid specificity issues:
/* app/assets/stylesheets/application.css */
@layer components {
.prose-content a {
@apply text-primary-600 underline hover:text-primary-800 dark:text-primary-400;
}
/* Third-party output you can't add classes to directly */
.trix-content h2 {
@apply text-lg font-semibold mt-6 mb-2;
}
}
If you can extract a component or partial instead, always prefer that.
Dark mode
Every element with color classes needs a dark: variant. Dark mode ships with the initial
implementation, not as a follow-up.
<!-- WRONG — dark mode forgotten -->
<div class="bg-white text-gray-900 border-gray-200">
<!-- RIGHT — both modes -->
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 border-gray-200 dark:border-gray-700">
- Contrast still matters. Dark mode isn't just inverting colors — maintain WCAG AA ratios
(4.5:1 normal text, 3:1 large text). Light text on dark: use
-100/-200shades; dark text on light:-800/-900. Avoid pure white on pure black — use off-whites and deep grays. - Adjust images that look wrong on dark backgrounds:
class="dark:brightness-90 dark:contrast-105". - Verify both modes after any UI change: text readable, borders visible, hover/focus states clear, icons and images don't vanish.
Responsive design
Mobile-first: start with the mobile layout, then add larger breakpoints.
<!-- Mobile: stack · Tablet: side-by-side · Desktop: sidebar grid -->
<div class="flex flex-col md:flex-row lg:grid lg:grid-cols-[250px_1fr]">
<nav class="p-4 md:w-64 lg:w-auto">…</nav>
<main class="p-4 flex-1">…</main>
</div>
Common patterns: grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3, hidden lg:block,
text-2xl md:text-3xl lg:text-4xl, px-4 md:px-8 lg:px-16.
Touch targets need adequate size on mobile — minimum 44×44px: class="min-h-[44px] min-w-[44px] px-4 py-2".
Accessibility
Styling affects accessibility directly.
- Visible focus for keyboard users. Use
focus-visible(notfocus) so the ring only shows for keyboard navigation, not mouse clicks — and never remove an outline without replacing it:class="focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:ring-offset-2". - Color is not the only signal. Pair color with an icon or text. An error field gets
aria-invalid="true"+ anaria-describedbymessage, not justborder-error-500. - Semantic HTML first.
<button>over<div role="button">;<nav>over<div aria-label="navigation">. - Screen-reader-only labels for icon-only controls:
<span class="sr-only">Delete post</span>. - Respect reduced motion:
class="transition-transform motion-reduce:transition-none motion-reduce:transform-none".
Anti-patterns
| Don't | Do instead | Why |
|---|---|---|
style="color: red" | text-error-500 | Inline styles bypass the design system |
bg-[#3b82f6] | bg-primary-500 | Arbitrary values can't be updated centrally |
| Copy-paste 15 classes | Extract a component | Components are the reuse mechanism |
Raw CSS in .css files | Tailwind utilities, or @apply in @layer | Plain CSS diverges from the system |
p-[13px] | p-3 (or extend the config) | Arbitrary spacing breaks visual rhythm |
Forget dark: variants | Pair light and dark always | Half your users see a broken UI |
| Forget breakpoints | Mobile-first, add md:/lg: | Mobile users are the majority |
focus: for focus rings | focus-visible: | Avoids focus rings on mouse clicks |
| Remove outline, no replacement | focus:outline-none focus-visible:ring-2 | Keyboard users must see focus |
Checklist for UI changes
- Existing component? — is there a partial/component/shared pattern that already handles this?
- Design tokens — colors, spacing, sizes from the theme, not arbitrary values.
- Lean classes — shorthand, drop defaults, consistent order (Prettier plugin).
- Dark mode — every color class has a
dark:pair, contrast holds. - Responsive — works from mobile up; touch targets ≥ 44px.
- Accessibility —
focus-visiblestates, semantic HTML,sr-onlylabels for icon-only buttons. - No plain CSS, no inline styles — utilities or
@applyin@layer componentsonly.
Adapted from the MIT-licensed mattsears/rails-cto rails-cto-tailwind skill, generalised beyond Rails.
Gives 0 of the 12 instructions most css styling skills give in ~2.5k tokens
Counted across 586 of the 596 authors here whose files we hold, read 2026-08-06
- avoid excessive centered layoutsin 55 of 586, across 12 files
- bundle code into single HTML filein 54 of 586, across 14 files
- Respect prefers-reduced-motion user settingsin 52 of 586, across 35 files
- avoid purple gradientsin 51 of 586, across 11 files
- avoid uniform rounded cornersin 51 of 586, across 11 files
- avoid Inter fontin 51 of 586, across 11 files
- edit generated files to develop artifactin 50 of 586, across 10 files
- animate only transform and opacity propertiesin 43 of 586
- Make touch targets at least 44x44 pixelsin 41 of 586, across 15 files
- Ensure minimum color contrast of 4.5:1in 39 of 586, across 10 files
- use tailwind cssin 39 of 586, across 24 files
- Use SVG icons instead of emojisin 38 of 586, across 11 files
Said here and by no other author read
- style with Tailwind utilities or @apply
- implement both light and dark modes
- use shorthand utilities
- keep class order consistent
- extract components to reduce class soup
- use focus-visible for keyboard rings
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.