Here is what you need to know about Tailwind CSS v4 (May 2025)
- New Engine - Performance First:
- V4 ships with a completely rewritten engine. Expect drastically reduced build times – typically sub-10ms for most projects, even large ones often under 100ms. This is achieved by more efficiently parsing sources and generating CSS on-demand.
- CSS-First Configuration via
@theme
:- The primary configuration mechanism shifts from
tailwind.config.js
(for theme values) to your main CSS file using the@theme
directive./* app.css */ @import "tailwindcss"; @theme { --font-sans: "Inter", system-ui, sans-serif; --color-brand-500: oklch(0.637 0.237 25.331); /* Example OKLCH color */ --breakpoint-lg: 64rem; --spacing: 0.25rem; /* Base for numeric spacing utilities */ }
- Theme values are defined as CSS custom properties (variables). Tailwind uses these to generate corresponding utility classes (e.g.,
font-sans
,bg-brand-500
,lg:p-(--spacing-4)
) and also makes these variables globally available for use in custom CSS or arbitrary values (e.g.,var(--color-brand-500)
). - The default theme is still provided but can be extended, overridden, or entirely replaced using this CSS-native approach. For instance,
--color-*: initial;
within@theme
will remove all default color utilities, allowing a fully custom palette.
- The primary configuration mechanism shifts from
- Modern CSS Baseline:
- Targets Safari 16.4+, Chrome 111+, Firefox 128+. This is non-negotiable as v4 relies on features like
@property
,color-mix()
, and modern cascade layers. Older browser support requires sticking to v3.4. - The default color palette leverages OKLCH for more vibrant, perceptually uniform colors out-of-the-box.
- Targets Safari 16.4+, Chrome 111+, Firefox 128+. This is non-negotiable as v4 relies on features like
- Simplified Imports:
- The
@tailwind base; @tailwind components; @tailwind utilities;
directives are deprecated. A single@import "tailwindcss";
now handles the injection of base styles (Preflight), theme variables, and utilities into their respective cascade layers.
- The
- Modular Tooling Packages:
- CLI:
npx @tailwindcss/cli ...
(package:@tailwindcss/cli
) - PostCSS Plugin:
@tailwindcss/postcss
(package:@tailwindcss/postcss
) - Vite Plugin:
@tailwindcss/vite
(package:@tailwindcss/vite
) - Recommended for Vite projects due to optimized performance and DX.
- CLI:
- Internalized Processing:
postcss-import
andautoprefixer
are generally no longer required as separate dependencies. Tailwind v4 handles CSS bundling and vendor prefixing (via Lightning CSS) internally.
- Configuration File Shift:
- While
tailwind.config.js
can still be used for plugin definitions or complex setups (loaded via@config "path/to/config.js";
), theme customization (colors, spacing, fonts, breakpoints) should primarily occur in CSS via@theme
. - The
content
array for source file scanning is still primarily configured via JS config if used, or Tailwind attempts automatic detection. Use@source
in CSS for explicit path additions/exclusions.
- While
- Utility Deprecations & Renames:
- The
npx @tailwindcss/upgrade
tool is highly recommended and automates most of this. - Opacity syntax is now consistently
bg-black/50
(no morebg-opacity-50
). - Scales for
shadow
,rounded
, andblur
have been normalized (e.g.,shadow
->shadow-sm
,shadow-sm
->shadow-xs
). ring
default width is now1px
(was3px
); usering-3
for the old default.
- The
- Default Value Adjustments:
- Default border color is now
currentColor
. Explicitly add color classes likeborder-gray-200
if you relied on the v3 default gray. - Default ring color is
currentColor
(wasblue-500
).
- Default border color is now
- Selector Modifications:
space-x-*
/space-y-*
utilities now usemargin-bottom
/margin-right
on:not(:last-child)
for performance. This might affect inline elements or layouts with existing tweaked margins. Flex/gridgap
is often a better alternative.- Variant stacking order is now left-to-right (e.g.,
dark:md:hover:bg-red-500
) for CSS-like consistency.
- Custom Utility Definition:
@utility
directive replaces@layer components
or@layer utilities
for defining custom, variant-aware utility classes. This ensures proper integration with Tailwind's engine and cascade layers.@utility btn-primary { background-color: var(--color-brand-500); /* ... */ }
- Functional utilities (e.g.,
tab-*
matchingtab-2
,tab-github
) are defined using@utility
with a--value()
function to parse arguments and match theme keys or arbitrary values.
@apply
in Scoped Styles (Vue SFCs, Svelte, CSS Modules):- Due to isolated processing of these style blocks by build tools, theme variables, custom utilities, and variants defined in global CSS are not automatically available.
- Use
@reference "../path/to/your/main.css";
inside the scoped style block to make these available without duplicating CSS output. - Alternatively, directly use CSS variables (
var(--color-brand-500)
) instead of@apply
for better performance and simpler processing.
- Prefix Syntax:
- Utility prefixes are now variant-like:
tw:bg-red-500
. Theme variables in@theme
remain unprefixed, but generated CSS variables will be prefixed (e.g.,--tw-color-red-500
).
- Utility prefixes are now variant-like:
- Arbitrary Value Syntax for CSS Variables:
- Using CSS variables in arbitrary values now uses parentheses:
bg-(--my-brand-color)
instead ofbg-[--my-brand-color]
. This resolves ambiguity with other arbitrary value types.
- Using CSS variables in arbitrary values now uses parentheses:
- Enhanced Variant System:
- Comprehensive support for ARIA attributes (
aria-checked:
,aria-disabled:
). Customaria-*
variants can be defined. - Data attribute variants (
data-[size=large]:
,data-active:
). :has()
pseudo-class support viahas-*
variants (e.g.,has-[:focus]:
).- Child (
*
) and descendant (**
) combinator variants (e.g.,*:p-2
,**:data-avatar:rounded-full
). group-*
andpeer-*
variants can now be named for more complex nesting/sibling scenarios (e.g.,group/item
,peer-checked/opt1:
).
- Comprehensive support for ARIA attributes (
- Container Queries:
- Enabled via
@container
class on the parent. - Size-based variants (
@sm:
,@lg:
, or arbitrary@min-[475px]:
) style children based on the container's width. - Named containers (
@container/sidebar
,@lg/sidebar:
) allow targeting specific ancestor containers. - Container query length units (
cqw
,cqi
) can be used in arbitrary values (e.g.,w-[50cqw]
).
- Enabled via
- Native CSS Features:
- Tailwind v4 is built upon and encourages the use of native CSS variables, nesting (processed by Lightning CSS),
color-mix()
,calc()
, etc.
- Tailwind v4 is built upon and encourages the use of native CSS variables, nesting (processed by Lightning CSS),
- Preprocessors (Sass/Less/Stylus):
- Not designed for use with Tailwind v4. Tailwind itself, with its CSS-native features and internal processing via Lightning CSS, fulfills most preprocessor roles.
theme()
Function in CSS:- Deprecated. Use
var(--css-variable-name)
instead. For media queries wherevar()
isn't supported,theme(--breakpoint-xl)
(using the CSS variable name) can be used.
- Deprecated. Use
corePlugins
in JS Config:- Disabling core plugins via JS config is no longer supported. Manage utility generation by not using unwanted classes or explicitly excluding them if necessary via
@source not inline(...)
.
- Disabling core plugins via JS config is no longer supported. Manage utility generation by not using unwanted classes or explicitly excluding them if necessary via
Tailwind CSS v4 represents a leaner, faster, and more CSS-idiomatic approach. The upgrade tool (npx @tailwindcss/upgrade
) is crucial for v3 projects. For new projects, understanding the CSS-first configuration and modern CSS dependencies is key.