Tailwind CSS is a utility-first CSS framework: instead of writing a stylesheet full of custom class names, you style elements with small, single-purpose classes such as p-4, text-lg and bg-blue-600. Tailwind CSS v4 changed how it is installed and configured, so many older tutorials no longer work. This handbook covers the current way to use it in 2026, from setup to production.
Tailwind v4 needs no tailwind.config.js for most projects: install it with your build tool, add @import "tailwindcss"; to your CSS, and customise your design tokens with @theme in the same file. It finds the classes you use automatically and outputs only those. Style mobile-first with prefixes like md: and hover:, extract repeated patterns into components rather than long @apply rules, and deploy the compiled CSS to any hosting.
1. What utility-first means
In traditional CSS you invent a class name, then write its rules elsewhere:
.card { padding: 1.5rem; border-radius: 0.75rem; background: white; box-shadow: 0 1px 3px rgb(0 0 0 / 0.1); }With Tailwind you apply the same styles directly in your markup:
<div class="p-6 rounded-xl bg-white shadow-sm">…</div>This looks busy at first, but it has practical advantages: you don't switch files or invent names, every value comes from a shared scale so designs stay consistent, and deleting markup deletes its styles. The trade-off is long class lists, which you manage by building reusable components in your framework or templates.
| Approach | Styling | Output size | Best for |
|---|---|---|---|
| Tailwind CSS | Utility classes in markup | Only the classes you use | Custom designs, component-based apps |
| Bootstrap | Pre-built components | Whole framework unless trimmed | Quick admin screens with a standard look |
| Hand-written CSS | Your own classes | Whatever you write | Small sites, full control |
For a wider comparison with design tokens and CSS architecture methods, see Modern CSS: Tailwind v4, Open Props and CUBE CSS.
2. Installing Tailwind CSS v4
Pick the method that matches your project. All of them need Node.js on your own computer (a current LTS release), not on your server.
With Vite (React, Vue, Svelte, plain HTML)
npm install tailwindcss @tailwindcss/viteAdd the plugin to vite.config.js:
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [tailwindcss()],
});Then put one line at the top of your main CSS file:
@import "tailwindcss";With PostCSS (Next.js and other PostCSS set-ups)
Install tailwindcss and @tailwindcss/postcss, then register the plugin in postcss.config.mjs:
export default { plugins: { '@tailwindcss/postcss': {} } };Next.js's create-next-app offers to set this up for you, and new Laravel projects ship with Tailwind configured through Vite.
With the standalone CLI (no bundler)
npm install tailwindcss @tailwindcss/cli
npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watchLink dist/output.css from your HTML. Add --minify and drop --watch for a production build.
Tailwind offers a browser build you can load with a script tag, which compiles styles in the visitor's browser. It is handy for trying ideas, but it is slower and not meant for production. Older tutorials load cdn.tailwindcss.com as a stylesheet link; that address is the v3 play script, so as a stylesheet it styles nothing.
3. Configuring your design in CSS
In v4, configuration lives in your CSS file. The @theme block defines design tokens, and each token generates matching utilities:
@import "tailwindcss";
@theme {
--color-brand-500: oklch(0.62 0.19 255);
--color-brand-700: oklch(0.48 0.17 255);
--font-display: "Poppins", sans-serif;
--breakpoint-3xl: 120rem;
}That gives you bg-brand-500, text-brand-700, font-display and a 3xl: breakpoint prefix. Tokens are also available as normal CSS variables, for example var(--color-brand-500).
Other directives you will use:
@plugin "@tailwindcss/typography";loads a plugin (install it with npm first).@utilitydefines your own utility class.@custom-variantdefines your own variant, such as a class-based dark mode (section 6).@source "../node_modules/my-ui";adds a folder that automatic class detection would otherwise skip.@config "./tailwind.config.js";keeps an old JavaScript config working while you migrate.
Tailwind scans your project for class names automatically, ignoring files in .gitignore, so the v3 content array and the even older purge option are no longer needed.
4. Core utilities you'll use every day
p-4, px-6, mt-8, gap-4, space-y-2. One unit is 0.25rem by default.text-sm to text-6xl, font-semibold, leading-relaxed, tracking-tight, text-center.bg-slate-900, text-white, border-gray-200. Add opacity with a slash: bg-black/50.flex, grid, grid-cols-3, items-center, justify-between, container, mx-auto.w-full, max-w-3xl, h-screen, size-10 for equal width and height.rounded-lg, border, shadow-md, ring-2, transition, duration-200.When a value isn't on the scale, use square brackets for a one-off: top-[117px] or bg-[#1da1f2]. If you use the same value more than twice, add it to @theme instead.
5. Responsive design and states
Tailwind is mobile-first. Unprefixed classes apply to every screen size; a prefix applies from that breakpoint upwards:
| Prefix | Applies from | Typical device |
|---|---|---|
| (none) | 0 | Phones |
| sm: | 40rem (640px) | Large phones |
| md: | 48rem (768px) | Tablets |
| lg: | 64rem (1024px) | Laptops |
| xl: | 80rem (1280px) | Desktops |
| 2xl: | 96rem (1536px) | Large screens |
So grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gives one column on phones, two on tablets and three on laptops.
State variants work the same way: hover:, focus-visible:, active:, disabled:. Use group on a parent and group-hover: on a child to style children when the parent is hovered. Container queries are built in: mark a parent with @container and use @md: on children to respond to the parent's width instead of the screen's.
A responsive navigation bar that stacks on phones:
<nav class="flex flex-col gap-4 p-4 md:flex-row md:items-center md:justify-between">
<a href="#top" class="text-xl font-bold text-brand-700">YourBrand</a>
<ul class="flex flex-col gap-2 md:flex-row md:gap-6">
<li><a class="hover:text-brand-500 focus-visible:underline" href="#services">Services</a></li>
<li><a class="hover:text-brand-500 focus-visible:underline" href="#contact">Contact</a></li>
</ul>
</nav>6. Dark mode
By default, the dark: prefix follows the visitor's operating-system setting (prefers-color-scheme):
<div class="bg-white text-slate-900 dark:bg-slate-900 dark:text-slate-100">…</div>To let users toggle it with a button instead, switch dark mode to a class and add or remove dark on the html element with JavaScript:
@custom-variant dark (&:where(.dark, .dark *));7. Keeping markup maintainable
Long class lists are manageable if you follow a few rules:
- Extract components, not CSS. In React, Vue, Blade or any template language, make a
ButtonorCardcomponent once and reuse it. This is the recommended way to avoid repetition. - Use
@applysparingly, for things you can't componentise, such as styling HTML from a CMS. In Vue or Svelte component style blocks, add@reference "../app.css";so@applycan see your theme. - Never build class names from strings.
bg-${color}-500won't work, because Tailwind only generates classes it can find written in full. Map values to complete class names instead, such as{ red: 'bg-red-500', green: 'bg-green-500' }. - Let a formatter sort classes. The official Prettier plugin for Tailwind orders classes consistently, and the Tailwind CSS IntelliSense extension for VS Code autocompletes them.
8. Upgrading from Tailwind v3
The official upgrade tool handles most of the work. Run it in a new Git branch and review the diff:
npx @tailwindcss/upgradeChanges to check by hand afterwards:
- Renamed utilities: the old
shadow-smis nowshadow-xsandshadowisshadow-sm(the same shift applies torounded,bluranddrop-shadow);outline-noneisoutline-hidden;bg-gradient-to-risbg-linear-to-r;flex-shrink-0isshrink-0. - Changed defaults:
ringis now 1px (usering-3for the old look), and borders default to the current text colour instead of grey. - Removed utilities:
bg-opacity-*and similar are gone; use the slash syntax such asbg-black/50. - Browser support: v4 targets modern browsers (Safari 16.4+, Chrome 111+, Firefox 128+). If you must support older browsers, stay on v3.4.
9. Running this on Domain India
Tailwind runs at build time, so what you deploy is an ordinary CSS file. That means a Tailwind site runs on any hosting:
- Shared hosting (cPanel, DirectAdmin, Webuzo): build on your computer (
npm run build), then upload the output folder topublic_htmlwith FTP or the File Manager. For PHP or Laravel projects, upload the compiled assets with the rest of the site. See what settings you need to upload your website. - App Platform: connect your repository and Node.js projects are detected and built automatically, so the Tailwind build runs on every deploy. Other stacks need a Dockerfile. Start with App Platform: getting started.
- VPS: self-managed, with full control over your build and web server.
- 25 GB NVMe SSD Storage
- 50 GB Monthly Bandwidth
- 1 Website
- 10 Email Accounts
- 512 MB RAM per app
- 1 vCPU
- 5 GB NVMe SSD
- PostgreSQL Database
Prices on the cards are Domain India list prices and exclude 18% GST.
Do I still need a tailwind.config.js file in Tailwind v4?
No, not for most projects. Tailwind v4 is configured in CSS: add @import "tailwindcss"; and define colours, fonts and breakpoints in an @theme block. An existing JavaScript config can still be loaded with the @config directive while you migrate.
How does Tailwind keep the CSS file small?
It scans your project for the class names you actually use and generates only those, so production CSS usually stays small. There is no purge or content setting to maintain in v4; add @source for any folder it doesn't scan automatically.
Can I use the Tailwind CDN in production?
No. The browser build compiles styles in the visitor's browser, which is slower, and Tailwind recommends it for prototypes only. Use the Vite plugin, PostCSS plugin or CLI to build a static CSS file for production.
Why are some of my Tailwind classes not working?
The usual causes are class names built from strings (such as bg-${color}-500), which Tailwind can't detect, files in a folder it doesn't scan (add it with @source), or v3 class names that were renamed in v4. Write class names in full and run the upgrade tool on older projects.
How do I add dark mode with Tailwind?
Add dark: variants such as dark:bg-slate-900. By default they follow the operating system's colour scheme. For a manual toggle, add @custom-variant dark (&:where(.dark, .dark *)); to your CSS and toggle the dark class on the html element.
Can I use Tailwind CSS on shared hosting?
Yes. Tailwind compiles to a normal CSS file at build time, so build the site on your computer and upload the output to your hosting account. The server doesn't need Node.js to serve it.
Ready to launch your Tailwind site? Compare cPanel hosting for static and PHP sites, the App Platform for Node.js builds, or open a support ticket if you need help uploading your build.
Upload your compiled site to shared hosting, or let the App Platform build your Node.js project on every deploy.
See hosting plans