Docs menu

Learning Logs · · 3 min read

Learning Tailwind CSS v4: from install to design tokens

Tailwind v4 from this site's real practice: Vite/CLI install, the utility-first mental model, mobile-first responsive, @theme design tokens, and when (not) to use @apply.

Tailwind CSS v4ViteDesign tokens

Tailwind CSS replaces long CSS files with utility classes right in your HTML. It looks “dirty” at first — until you realize you never think about class naming again, and never fear deleting old CSS. The site you’re reading is built entirely with Tailwind v4; this tutorial is how I use it.

1. Installation (Tailwind v4)

Prerequisite: Node.js 20+. Two paths, pick per project:

With Vite (Vue, React, Astro):

npm install tailwindcss @tailwindcss/vite
// vite.config.js
import tailwindcss from "@tailwindcss/vite";
export default { plugins: [tailwindcss()] };

With the CLI (any project — the way this site does it):

npm install tailwindcss @tailwindcss/cli
npx @tailwindcss/cli -i styles/input.css -o public/site.css --watch

Then one line in your CSS file — in v4 there’s no mandatory tailwind.config.js anymore:

/* styles/input.css */
@import "tailwindcss";

2. The mental model: utilities, not CSS components

<!-- Before: write CSS, name it, maintain it forever -->
<button class="btn-primary">Buy</button>

<!-- Tailwind: the styling reads in place -->
<button class="bg-teal-600 px-4 py-2 text-white hover:bg-teal-700">Buy</button>

The classes you’ll use most in week one: spacing (p-4, mt-6, gap-3), layout (flex, grid, items-center, justify-between), typography (text-sm, font-semibold, tracking-tight), color (bg-*, text-*, border-*).

3. Responsive & states: prefixes, not media queries

<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
  <!-- 1 column on phones, 3 columns from 768px up -->
</div>

<a class="text-zinc-500 transition-colors hover:text-zinc-900">Link</a>

The rule is mobile-first: unprefixed classes apply at every size, md: overrides from 768px up. This is the one mental model you must lock in.

4. Design tokens with @theme (v4)

This site’s brand colors are defined once, then become utilities automatically:

@import "tailwindcss";

@theme {
  --color-ink: #09090b;
  --color-accent: #0d9488;
  --font-display: "Geist", sans-serif;
}

Now text-ink, bg-accent, font-display are available everywhere — consistency without extra discipline.

5. Repeated classes? Componentize, don’t @apply

When the same run of classes appears in five places, don’t rush to @apply — extract a component (JSX/Blade/Vue) so markup + styling travel together. I use @apply sparingly, only for global design-system patterns like .btn-primary.

Tips from experience

  • Install the Tailwind CSS IntelliSense editor extension — autocomplete + color previews transform the learning experience.
  • Tailwind only generates classes it finds written out in scanned files — dynamically assembled classes ("text-" + color) won’t exist in the output. Write classes in full.
  • The classic bug that once bit this site: content min-width exceeding a phone’s viewport. Memorize the antidote trio: min-w-0, truncate, and flex-wrap.
  • v4 is much faster and CSS-first in configuration — if another tutorial tells you to create tailwind.config.js + content: [...], that’s v3 style.

Want something like this built for your business?