Tailwind CSS: A Practical Guide for Web Developers
Install Tailwind CSS, build responsive interfaces with utility classes, customize themes, enable dark mode, and troubleshoot common setup issues.
Tailwind CSS is a build-time CSS framework: it scans your project files for class names, generates the CSS those classes need, and writes a static stylesheet for your app. You build interfaces by composing single-purpose utility classes in your markup, then use variants such as hover:, focus:, and responsive prefixes to apply styles conditionally.
For a new project, choose the Tailwind integration that matches its framework and build pipeline. This guide uses Vite as a concrete setup, then covers responsive layouts, dark mode, customization, production checks, and common problems. Tailwind’s documentation changes by version, so check your installed package version and use its matching docs before copying commands. The compatibility figures below are specifically for Tailwind CSS v4.0.
1. How do I install Tailwind CSS?
Tailwind provides setup routes for Vite, PostCSS, its CLI, and many frameworks. Pick the route that fits the project’s existing build system; avoid adding a second CSS pipeline when the framework already has an integration. The commands here follow the official Vite installation route for Tailwind v4.
Install with Vite
- Create a Vite project if you do not already have one, or open the existing project.
- Install Tailwind and its Vite plugin:
npm install tailwindcss @tailwindcss/vite
- Add the plugin to your Vite configuration:
// vite.config.js
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})
- Import Tailwind in the CSS entry point that your app loads:
/* src/style.css (or the CSS entry point used by your app) */
@import "tailwindcss";
- Make sure that CSS entry point is imported by your application. For example:
// src/main.js
import './style.css'
- Start the development server and confirm the generated styles appear in the browser:
npm run dev
Use the official Tailwind Vite installation guide and framework guides for the instructions matching your framework and installed version.
Other setup routes
- PostCSS: Use the official PostCSS integration when PostCSS is already part of your build pipeline. Follow the current version’s installation guide rather than copying configuration from another Tailwind major version.
- Tailwind CLI: Use the CLI when you want Tailwind to compile CSS without integrating a framework-specific plugin. Follow the official CLI instructions for the installed version.
- Framework guide: Choose the framework-specific instructions when the framework manages CSS entry points or bundler configuration.
- Play CDN: Useful for a quick browser experiment. Tailwind explicitly says the Play CDN is for development and is not intended for production.
See official installation options and the Play CDN guidance.
2. How do I use Tailwind CSS?
Compose utilities on the element they style. Each class represents a focused property or behavior, so several classes can describe layout, spacing, typography, color, and interaction together.
<article class="mx-auto max-w-xl rounded-xl bg-white p-6 shadow-md">
<p class="text-sm font-semibold text-indigo-700">Getting started</p>
<h1 class="mt-2 text-2xl font-bold tracking-tight text-slate-900">
Build a clear interface
</h1>
<p class="mt-3 leading-7 text-slate-600">
Combine focused utilities to describe how this card looks and behaves.
</p>
<a class="mt-5 inline-flex rounded-md bg-indigo-600 px-4 py-2 font-medium text-white hover:bg-indigo-500 focus:outline-2 focus:outline-offset-2 focus:outline-indigo-600"
href="/guide">
Read the guide
</a>
</article>
For example, p-6 adds padding, rounded-xl rounds corners, and hover:bg-indigo-500 changes the background on hover. Utilities do not eliminate custom CSS: use custom styles when they make a complex or repeated design easier to understand. Tailwind’s guide to styling with utility classes explains the model.
Class detection and dynamic names
Tailwind generates styles for class candidates it detects in source files. Keep complete class names visible in scanned source. Building a class name by concatenating fragments can prevent Tailwind from detecting the intended utility.
// Avoid constructing utility names from fragments:
const colorClass = `bg-${color}-600`
// Prefer complete candidates that the scanner can see:
const colorClasses = {
blue: 'bg-blue-600 hover:bg-blue-500',
green: 'bg-green-600 hover:bg-green-500',
}
const className = colorClasses[color] ?? colorClasses.blue
For class candidates in files outside the normal scan, consult class detection documentation for the installed version and configure source detection as needed.
3. How do Tailwind variants work?
Variants scope a utility to a state or condition. Prefix a utility with a variant and a colon: hover:bg-blue-700 applies the background when the element is hovered; focus:outline-2 applies an outline when it is focused. State, media, group, and arbitrary variants can be combined when the design calls for multiple conditions.
<div class="group rounded-lg p-4 hover:bg-slate-50">
<a class="font-medium text-slate-900 group-hover:text-blue-700 focus-visible:outline-2"
href="/details">
View details
</a>
</div>
Use state variants for interaction feedback, and provide a visible keyboard focus style for interactive controls. Use group variants when a child’s style depends on a parent state. The utility classes documentation covers variants and their combinations.
4. How do Tailwind breakpoints work?
Tailwind is mobile-first: unprefixed utilities set the base style, and a responsive prefix applies a style from its minimum width upward. The documented default breakpoints are:
| Prefix | Minimum width | Pixel equivalent |
|---|---|---|
sm |
40rem | 640px |
md |
48rem | 768px |
lg |
64rem | 1024px |
xl |
80rem | 1280px |
2xl |
96rem | 1536px |
For example, the following card uses one column by default and two columns from the md breakpoint upward:
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
<section class="rounded-lg p-4">First item</section>
<section class="rounded-lg p-4">Second item</section>
</div>
A prefixed utility generally remains active at larger widths. If a style should apply only across a bounded range, use a range-limiting variant supported by your installed version. Check the actual design at widths just below and above each threshold; a breakpoint is a condition, not a guarantee that the layout fits. See responsive design documentation.
5. How do I enable dark mode in Tailwind CSS?
By default, the dark: variant follows the operating system or browser prefers-color-scheme preference. Apply dark variants alongside your base styles:
<main class="bg-white text-slate-900 dark:bg-slate-950 dark:text-slate-100">
<h1 class="text-2xl font-bold">Account settings</h1>
<p class="mt-2 text-slate-600 dark:text-slate-300">
Manage your preferences.
</p>
</main>
If users can select a theme in your app, redefine the dark variant to use an application-controlled class or data attribute, then set that selector in application code. For example, a class-based approach can add a theme class to a root element and remove it when the user chooses light mode. Keep the selector and the variant configuration aligned; otherwise the dark utilities will never activate. Follow the version-specific dark mode documentation.
6. How do I customize Tailwind CSS?
Use theme variables for values that belong to the design system, such as brand colors, font families, and spacing conventions. This gives repeated designs a shared source of truth. For a genuine one-off value, an arbitrary value can be more direct. Add custom CSS, utilities, or variants when they express a reusable rule that does not fit the built-in utilities.
/* Illustrative theme extension; use the syntax for your installed version. */
@import "tailwindcss";
@theme {
--color-brand: #3157d5;
--font-display: "Inter", sans-serif;
}
<h1 class="font-display text-3xl text-brand">A branded heading</h1>
<div class="w-[37rem]">A one-off width when the design requires it</div>
The snippet uses the v4 theme-variable style; do not paste it into an older project without checking that version’s configuration model. Prefer a token for a value repeated across components. Arbitrary values are useful for exceptions, but repeated one-off values make later design changes harder. See theme variables and adding custom styles.
7. What should I check before using Tailwind in production?
- Version: Inspect the installed Tailwind package and follow the matching installation and configuration documentation. Major versions can use different integration patterns.
- CSS delivery: Confirm the compiled stylesheet is included by the app’s entry point and is present in the production build.
- Source detection: Confirm templates and component files are scanned. Keep complete class candidates in source instead of assembling names dynamically.
- Responsive behavior: Review layouts at narrow widths and around every breakpoint used.
- Interaction states: Check hover and keyboard focus behavior, plus disabled or other states relevant to the component.
- Theme behavior: Test both system preference and the app’s theme selector, if available.
- Browser support: Tailwind v4.0 documents a core browser floor of Chrome 111, Safari 16.4, and Firefox 128. Confirm the compatibility page for your exact version and target audience.
- Build tools: Tailwind v4 is not designed for Sass, Less, or Stylus. Verify compatibility before migrating a project that depends on those preprocessors.
These compatibility statements are scoped to v4.0 and should not be generalized to every Tailwind release. Check the official compatibility page before setting browser requirements or planning a migration.
Performance, reliability, and cost
Tailwind’s documented model generates a static CSS file from detected candidates at build time; it is not a runtime styling engine. The practical reliability concern is whether the build sees the source classes and whether the resulting CSS reaches the page. Keep the build reproducible, include the stylesheet, and verify production output. No comparative performance benchmark is asserted here. Tailwind is software; this guide makes no claim about licensing or hosting cost. Evaluate those against the version and distribution you choose.
8. Troubleshooting common Tailwind problems
| Symptom | Likely cause | What to do |
|---|---|---|
| None of the utilities style the page | Tailwind is not integrated into the build, the CSS entry point is not imported, or the compiled stylesheet is not loaded. | Check the version-matched installation steps, Vite or framework plugin configuration, CSS import, and browser network panel for the stylesheet. |
| A class works in development but disappears in production | The class candidate is assembled dynamically or its file is not included in source detection. | Use complete class strings and configure detection for the source location using the relevant version’s docs. |
| Some utilities work but a new utility does not | The candidate may be misspelled, unsupported in the installed version, or absent from scanned source. | Check spelling, package version, and source detection; rebuild after correcting the issue. |
| Vite reports a plugin or CSS import error | The setup may mix instructions from different Tailwind versions or omit a dependency. | Check installed package versions and follow one matching integration guide end to end. |
| Dark styles never appear | The system preference is light, or a custom selector does not match the configured dark variant. | Test with a dark system preference or align the app’s class/data attribute and variant configuration. |
| A tablet or desktop layout changes at the wrong width | The prefix uses a minimum-width breakpoint, or the chosen default threshold does not fit the design. | Check the documented breakpoint values and test above and below the threshold; customize the design tokens if the project needs different thresholds. |
| Styles are missing only in older browsers | The target browser may fall below the installed Tailwind version’s supported baseline. | Check the compatibility docs for that exact version and choose a supported version or adjust browser support requirements. |
| The project’s Sass/Less/Stylus pipeline conflicts with v4 | Tailwind v4 is not designed for those preprocessors. | Review the compatibility guidance and select an integration and version that fits the project’s build pipeline. |
9. Or skip the browser setup
If your workflow needs screenshots of pages styled with Tailwind, ScreenshotNeo is a website screenshot API and MCP server. You can request a rendered page with one API call instead of setting up a browser capture flow. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed, and response headers indicate the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.
10. Frequently asked questions
Is Tailwind CSS a runtime styling engine?
No. It scans source files and generates a static stylesheet at build time.
Do I need to write custom CSS if I use Tailwind?
You can use utilities for much of an interface, but custom CSS remains available for reusable or specialized rules that are clearer outside markup.
Can I use Tailwind v4 with Sass?
Tailwind’s v4 compatibility documentation says v4 is not designed for Sass, Less, or Stylus. Check the guidance for your exact version and build system.
Can I use arbitrary values everywhere?
They are useful for real exceptions. If a value repeats or represents a design decision, make it a shared theme token instead.


