Tailwind CSS generates static CSS by scanning class names in your source files. It is useful for building components within a consistent design scale, but it does not decide your semantics, component boundaries, or accessibility for you.
This guide focuses on Tailwind CSS 4. Older tutorials based on @tailwind base, @tailwind components, and @tailwind utilities may not match a modern setup.
Install with the CLI
npm install tailwindcss @tailwindcss/cli
Import Tailwind in your entry CSS:
@import "tailwindcss";
Run the CLI:
npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch
For Vite, Next.js, or other frameworks, prefer Tailwind's official integration guide for that framework instead of forcing the raw CLI command into every project.
Utility-first example
<article class="rounded-xl border border-zinc-800 bg-zinc-950 p-6 text-zinc-100 shadow-lg">
<h2 class="text-xl font-semibold">FreeMac</h2>
<p class="mt-2 text-sm leading-6 text-zinc-400">
Free Mac apps and migration guides for Windows switchers.
</p>
</article>
Many classes do not automatically mean the code is unmaintainable. The better question is whether the component has a clear responsibility, repeated patterns are extracted at the right level, and design values remain consistent.
Responsive and state variants
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
<!-- cards -->
</div>
<button class="bg-amber-600 hover:bg-amber-500 focus-visible:outline-2 disabled:opacity-50">
Save
</button>
Tailwind's responsive model is mobile-first: base classes apply everywhere, and breakpoint variants override them upward.
Do not write only hover: states. Include keyboard focus, disabled states, and touch device behavior where relevant.
Theme variables
Tailwind 4 lets you define theme variables in CSS:
@import "tailwindcss";
@theme {
--color-brand-500: oklch(0.72 0.12 75);
--font-display: "Noto Serif SC", serif;
}
Then use them in classes:
<h1 class="font-display text-brand-500">Mac for Free Minds</h1>
If your project already has CSS variables, do not rebuild everything just for Tailwind. Decide which tokens belong to the product theme and which are local implementation details.
Do not dynamically build incomplete class names
The scanner needs to see complete class strings:
// Avoid
const className = `text-${color}-600`
// Prefer
const colors = {
red: "text-red-600",
green: "text-green-600",
}
Classes from CMS content or user input should not be trusted blindly. They may not generate stable CSS and can make the UI hard to control.
When to extract a component
Repeated buttons should not be maintained by copying long strings everywhere:
type ButtonProps = {
children: React.ReactNode
tone?: "primary" | "quiet"
}
const tones = {
primary: "bg-amber-600 text-white hover:bg-amber-500",
quiet: "bg-zinc-800 text-zinc-100 hover:bg-zinc-700",
}
export function Button({ children, tone = "primary" }: ButtonProps) {
return (
<button className={`rounded-md px-4 py-2 font-medium ${tones[tone]}`}>
{children}
</button>
)
}
Extract React components when behavior, semantics, and API are reused. Use custom CSS classes only when a stable utility group truly belongs in CSS.
Common problems
- Styles are missing: check source paths and complete class names.
- Old config examples do not work: confirm Tailwind major version.
- Classes conflict: define clear merge rules for reusable components.
- Production CSS is too large: check scan paths and uncontrolled content.
- Pages still look inconsistent: build theme tokens and component rules; Tailwind alone is not a design system.
Related FreeMac guides
- For spacing, read Tailwind CSS Spacing: How the Scale Works.
- For directives and
@apply, read Tailwind CSS Directives: @apply, @layer, theme, and screen. - For React abstraction boundaries, read React Component Design: Composition, Abstraction, and Reuse.
Continue reading
Tailwind CSS Directives: @apply, @layer, theme, and screen
Understand Tailwind CSS directives and functions such as @apply, @layer, @config, theme(), screen(), and when not to hide every utility class inside CSS.
9 min readCSS 3D: perspective and transform-style Explained
Understand CSS 3D transforms through perspective, transform-style: preserve-3d, translateZ, rotateY, flattening, and parent-child 3D scene setup.
7 min readReflow and Repaint: Why CSS Animations Get Janky
Understand browser rendering steps, reflow, repaint, compositing, and why transform and opacity are usually better animation targets than width, height, top, or left.
Subscribe to FreeMac
Weekly picks: free Mac software reviews, trusted source updates, alternatives, and low-friction guides.