npm / tailwindcss
tailwindcss
What changed in tailwindcss 3 to 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-17.
7 breaking2 deprecations31 new APIs and options2 performance28 behavior and defaults11 tooling100 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli inittailwindcss 4180 changes
Breaking changes 7
Selectors combining an attribute selector and element selector without spacing are parsed as two selectors.
This syntax now generates font-size declarations instead of color declarations.
Requires --value(…) in functional @utility definitions.
Logical end utilities are canonicalized into corresponding
inset-e-*utilities, including negative versions.Logical start utilities are canonicalized into corresponding
inset-s-*utilities, including negative versions.Placeholder utilities now read their color from
--placeholder-color.The deprecated
overflow-ellipsisutility is canonicalized intotext-ellipsis.
Deprecations 2
The end-* utilities are deprecated in favor of inset-e-* utilities.
The start-* utilities are deprecated in favor of inset-s-* utilities.
New APIs and options 31
The CLI supports polling watch mode when filesystem events are unreliable or unavailable.
Adds an option to suppress CLI output.
Adds the @container-size utility.
Adds scrollbar-width utilities for auto, thin, and none values.
Adds scrollbar-gutter utilities.
Adds tab utilities.
Supports --default(…) inside --value(…) and --modifier(…) for functional utility definitions.
Adds zoom utilities.
The standalone CLI now supports the
NODE_PATHenvironment variable.Adds utilities for block-size.
Adds utilities for border-block-end.
Adds utilities for border-block-start.
The default theme now includes mauve, olive, mist, and taupe color palettes.
Adds a utility for font-feature-settings.
Adds utilities for inline-size.
Adds utilities for inset-block-end.
Adds utilities for inset-block-start.
Adds utilities for inset-inline-end.
Adds utilities for inset-inline-start.
Adds utilities for max-block-size.
Adds utilities for max-inline-size.
Adds utilities for margin-block-end.
Adds utilities for margin-block-start.
Adds utilities for min-block-size.
Adds utilities for min-inline-size.
Adds utilities for padding-block-end.
Adds utilities for padding-block-start.
Adds utilities for scroll-margin-block-end.
Adds utilities for scroll-margin-block-start.
Adds utilities for scroll-padding-block-end.
Adds utilities for scroll-padding-block-start.
Performance 2
Scanning JSONL and NDJSON files is faster.
The Oxide scanner performs fewer file system walks in bigger projects.
Behavior and default changes 28
Bare spacing values now work with auto-cols utilities.
Bare spacing values now work with auto-rows utilities.
Can now be used with CSS mixins.
One-valued spacing utilities generate var(--spacing) instead of calc(var(--spacing) * 1).
Can now be used inside addBase.
Adds parentheses when whitespace removal would hurt readability.
Preserves the original unit in arbitrary values instead of converting to base units.
Canonicalizes arbitrary :has() variants to the has-[…] form.
Allows multiple utility definitions with the same name when their value types differ.
Allows @variant to use stacked variants such as hover:focus.
Allows @variant to use compound variants such as hover and focus.
Border side utility combinations are canonicalized into axis or all-side utilities.
.envand.env.*are now excluded from default content-file scanning.The upgrade process no longer migrates files ignored by git.
Axis-specific overflow utilities are canonicalized into the combined overflow utility.
Axis-specific overscroll utilities are canonicalized into the combined overscroll utility.
Equivalent arbitrary padding utilities are canonicalized into shorthand utilities.
Scroll margin side combinations are canonicalized into axis or all-side utilities.
Scroll padding side combinations are canonicalized into axis or all-side utilities.
Canonicalization now prefers non-negative tracking utilities.
Canonicalizes calc(var(--spacing)*…) expressions into the --spacing(…) form.
Aspect-ratio fractions may now use multiples of .25, such as aspect-8.5/11.
The .jj directory is now ignored by default during content detection.
Utility names may now contain escape characters, improving formatter support.
Arbitrary utilities are now canonicalized to bare values when possible.
Candidate validation now behaves more like Oxide.
Canonicalization now combines text-* and leading-* classes.
Upgrade processing canonicalizes utilities containing 0 values.
Tooling 11
Named opacity modifiers now receive class suggestions from --opacity theme values.
Class candidates adjacent to Template Toolkit delimiters are now extracted from .tt, .tt2, and .tx files.
Class candidates are now extracted from Twig addClass calls.
Can be installed in Rspack projects without webpack as a peer dependency.
The v3-to-v4 migration now uses
config.content.Adds support for Vite 8 in the Tailwind CSS Vite integration.
The CLI emits a comment when source maps are saved to files.
A new package runs Tailwind CSS as a webpack plugin.
CSS parse errors now include the filename and line numbers, making failures easier to locate.
The environment API is now supported in the Vite integration.
The deprecated break-words utility is migrated to wrap-break-word during upgrades.
Fixes and other changes 99
Achromatic theme colors no longer shift hue when mixed in polar color spaces such as oklch.
Arbitrary hex colors now match theme colors case-insensitively during canonicalization.
CSS nesting is handled even when Lightning CSS is not run, including browser builds and Tailwind Play.
Fractional opacity modifiers now work with named shadow, text-shadow, drop-shadow, and inset-shadow sizes.
Preflight no longer overrides Firefox's native focus-visible outline styles for iframes.
The watcher dependency loads only for CLI watch mode, allowing one-off builds and polling when it cannot be loaded.
Explicit platform fonts replace generic system fonts so CJK text respects the page's lang attribute on Windows.
Earlier @source rules for nested files are scanned even when later rules reference parent folders.
--spacing(0)now optimizes to0px, preserving its length type inside calc expressions.PostCSS rebuilds when a preprocessor changes input CSS without changing the input file on disk.
The upgrade command no longer rewrites ignored files when run from a subdirectory.
Vite integration no longer triggers full page reloads for scanned files not yet loaded as modules.
JS plugins now resolve theme colors correctly when similarly prefixed color variables coexist.
Class candidates are now extracted from conditional Maud syntax.
Position try rules no longer trigger unknown at-rule warnings during CSS optimization.
Source patterns no longer scan unrelated sibling files and folders.
Watch mode no longer crashes on Windows when @source points to a missing directory.
Watch mode now rebuilds when the input CSS file changes in an ignored directory.
Prevents type errors when used with newer PostCSS patch releases.
Avoids HMR crashes when scanned files or directories are deleted.
Avoids crashes in Deno v2.8.x when context.parentURL is not a valid URL.
Variants used in addBase can now reference custom variants defined later.
Canonicalization avoids suggesting large spacing-scale values for arbitrary lengths.
Canonicalization no longer suggests invalid calc expressions.
Canonicalization no longer folds divisions when the result would require high precision.
Color utilities now work with custom shadow values containing calc expressions.
Upgrade no longer migrates empty class rules to invalid @utility rules.
Transitions between inset-shadow-none and other inset shadows now work correctly.
Removes deprecation warnings on Node 26 and newer.
Correctly negates @container queries, including style queries.
Canonicalization no longer crashes when plugin utilities throw for unsupported values.
Class candidates are now extracted from Twig removeClass calls.
No longer crashes when scanning files containing invalid UTF-8 bytes.
Source globs with symlinks are preserved.
Later source rules can re-include files excluded by earlier source-not rules.
Explicitly referenced source directories are scanned even when ignored by git.
Source globs ending in **/* preserve dynamic path segments and avoid scanning too many files.
Zero-valued spacing utilities generate 0 instead of calc(var(--spacing) * 0).
Standalone CLI binaries are ignored when scanning for class candidates.
Watch mode recovers when a tracked dependency is deleted and restored.
Serves ESM type declarations to ESM importers.
Fixes incorrect sourcemap warnings when using the Vite integration.
No longer crashes when scanning files containing invalid UTF-8 bytes.
Preserves significant underscore whitespace during canonicalization.
Prevents legacy end utilities without values from generating CSS.
Resolves relative @import paths from the correct directory with @tailwindcss/vite.
Prevents the upgrade process from migrating inline style attributes.
Preserves required whitespace around operators in negated arbitrary values.
Resolves package JavaScript entries instead of browser CSS entries with @tailwindcss/vite.
Resolves relative @plugin paths from the correct directory with @tailwindcss/vite.
Exports the missing PluginWithConfig type from tailwindcss/plugin for plugin config type inference.
Prevents legacy start utilities without values from generating CSS.
Resolves imports relative to base when result.opts.from is not provided.
Ensures CSS files containing @variant are processed by @tailwindcss/vite.
Imports in @import and @plugin now resolve correctly when using Vite aliases in @tailwindcss/vite.
Invalid characters exceeding the valid Unicode code point range no longer cause a crash.
Negative arbitrary values move the minus sign inside the arbitrary value.
Negative arbitrary margin values move the minus sign outside the arbitrary value.
Stopping the upgrade process no longer empties files while the process is running.
Imports with query parameters are now treated as unique resources.
Prevents crashes when candidates contain prototype properties such as row-constructor.
Prevents crashes when canonicalizing utilities containing @property at-rules.
Improves canonicalization for bare values exceeding default spacing scale suggestions.
Prevents canonicalization from returning an empty list instead of the expected utility.
Skips full reloads for server-only modules scanned by client CSS with @tailwindcss/vite.
Trailing dashes in functional utility names are allowed for backwards compatibility.
Classes containing periods within curly braces in MDX files are now detected correctly.
Astro v5 import aliases now work without crashing with the Vite integration.
Utility detection now handles names containing capital letters followed by numbers.
Prevents color-mix values from receiving a double @supports wrapper.
Class extraction now works correctly for Rails strict locals.
The @source inline() argument may now contain surrounding whitespace.
Changes to external files listed via @source now trigger a full page reload with the Vite integration.
Utility name validation now matches Oxide scanner rules.
Using @variant inside @custom-variant no longer causes an infinite loop.
Arbitrary property utilities with a top-level ! in the value are now skipped correctly.
The CLI now handles duplicate command-line arguments correctly.
Color-mix fallback rules are no longer emitted inside keyframes.
Backwards compatibility for the content theme key in JavaScript configs is improved.
The CLI no longer hangs when its output is /dev/stdout.
The upgrade process now handles future and experimental configuration keys.
JavaScript configs now handle special defaults such as ringColor.DEFAULT correctly.
Comments in Ruby files are skipped when checking for class names.
Validation of source(…) now happens relative to the file containing it.
Theme keys from JavaScript configs and plugins now preserve their original case.
The CLI now writes source maps correctly when running in watch mode.
Legacy JavaScript APIs now substitute @variant correctly.
Prevents an occasional crash on Windows when Tailwind CSS is loaded into a worker thread.
Canonicalization of arbitrary variants with attribute selectors is fixed.
Canonicalization is improved for & > :pseudo and & :pseudo arbitrary variants.
Candidates with an empty data type are discarded.
Invalid colors caused by nested & are fixed.
At-rules parse correctly when they contain a tab character.
Safari devtools rendering is fixed when Tailwind uses color-mix fallbacks.
Lightning CSS warnings for :deep, :slotted, and :global are suppressed.
Important utilities no longer affect other utilities.
Named groups now work with not-*, has-*, and in-* variants.
The theme(…) function no longer indexes into strings.
Theme keys are resolved correctly when one key name starts with another in JS configs and plugins.
tailwindcss 31 changes
Fixes and other changes 1
Fixed sibling-*() functions used inside calc(…) so they no longer break.