NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #907 most downloaded on npm
A utility-first CSS framework for rapidly building custom user interfaces.
Last release 11 days ago
08 Sep 2026
Ships on a steady schedule
a new release about every 8 days
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
9 years old
2657 releases · first in 2017
Respect preserveHtmlElements option even when using custom PurgeCSS extractor
### Changed - Upgrade to PostCSS 8
One column per quarter.
Support deep merging of arrays of objects under extend
extend (#2700)Support flattening deeply nested color objects
Support extend in variants configuration
space and divide utilities (#2644)space and divide utilities ignore elements with [hidden] now instead of only ignoring template elements (#2642)body, not just html (#2643)whitespace-no-wrap to whitespace-nowrap (#2664)New @apply implementation, slight backwards incompatibilities with previous behavior
Warning: This is a pre-release. I don't plan for anything to change (otherwise I would have already changed it) but things probably still will. There are probably also obviously broken embarrassing mistakes I haven't noticed because I'm so deep in the rabbit hole. Please test, help me fix them, and have some sympathy for me 😅
2xl breakpointtop-16 and stuff by default now)@apply works with everything nowoverflow-ellipsis and overflow-clip utilities (#1289)transform-gpu to force hardware acceleration on transforms when beneficial (#1380)inset plugin (#2630)@apply with complex classes (#2159)2xl breakpoint (#2609)group-hover for color utilities by default (28985b6)focus for z-index utilities by default (ae5b3d3)@apply implementation, slight backwards incompatibilities with previous behavior (#2159)truncate class to textOverflow core plugin (#2562)target feature and dropped any compatibility with IE 11 (#2571)normalize.css to modern-normalize (#2572)scrolling-touch and scrolling-auto utilities (#2573)space and divide utilities (#1883)theme retrieve the expected resolved value when theme value is complex (e13f083c4)The presets feature had unexpected behavior where a preset config without its own presets key would not extend the default config.
The presets feature had unexpected behavior where a preset config without its own presets key would not extend the default config. (#2662)
If you were depending on this unexpected behavior, just add presets: [] to your own preset to exclude the default configuration.
Fix issue where using theme with default line-heights did not resolve correctly
theme with default line-heights did not resolve correctly (#2308)Fix issue changing plugins defined using the withOptions API would not trigger rebuilds in watch processes
withOptions API would not trigger rebuilds in watch processesRemove console warnings about upcoming breaking changes (see note below)
tailwindcss init --full scaffolded a corrupt config file (https://github.com/tailwindlabs/tailwindcss/issues/2556)I've opted to remove the console notices about upcoming breaking changes (that encouraged users to opt-in to future features using the future option in their config file.)
While I had good intentions for this approach originally, I'm realizing now that it just ends up creating more confusion and a sloppier documentation story. Any breaking changes can't really be documented easily because the documentation needs to show the stable version of any given feature, since we can't assume someone has opted in to the new stuff.
This means that when someone does opt in, they are basically opting in to being out of sync with the documentation, which is a crappy experience for them, especially if they can't upgrade to Tailwind 2.0 in the near future because they need to support IE11.
For this reason I've decided to stop warning about the upcoming breaking changes so that we don't force users to opt-in to an essentially undocumented version of the framework. Instead we will continue to maintain the "upcoming changes" page in the docs, and continue to ship new ideas behind flags for people to test but without the nudge to upgrade. Folks who are comfortable opting-in to the new stuff early can do so, and folks that aren't can comfortably keep using things the way they are (along with complete documentation) and upgrade to the next version all at once, like people have done traditionally with most dependencies.
I will always strive to make breaking changes as painless and minimal as possible, so spending an hour to do the upgrade in one sitting is never going to be too bad. I highly value backwards compatibility and will never make needlessly breaking changes. An improvement is only worth making if it improves things enough to make up for the upgrade cost, and that's usually pretty rare. For example lh-5 might be a nicer class name than leading-5 but it is absolutely not worth breaking everyone's muscle memory and forcing them to replace hundreds of instances of classes in their projects. We'll only make breaking changes if they unlock meaningful new possibilities or fix fundamental problems that are holding people back.
tailwindcss init --full scaffolded a corrupt config file (https://github.com/tailwindlabs/tailwindcss/issues/2556)Merge plugins when merging config with preset (#2561
word-wrap and overflow-wrap together, not one or the other since word-wrap is IE-onlyDon't import corePlugins in resolveConfig to avoid bundling browser-incompatible code
corePlugins in resolveConfig to avoid bundling browser-incompatible code (#2548)Tailwind CSS v1.9 is now available with a new presets feature, some new utilities, and a few accessibility improvements. Check it out!
Tailwind CSS v1.9 is now available with a new presets feature, some new utilities, and a few accessibility improvements. Check it out!
presets config option (#2474)tailwind.config.js files with available future flags commented out (#2379)col-span-full and row-span-full (#2471)outline configurable, outline-none more accessible by default, and add outline-black and outline-white (#2460)rotate and skew values (#2528)xl, 2xl, and 3xl border radius values (#2529)grid-auto-columns and grid-auto-rows (#2531)defaultLineHeights and standardFontWeights from experimental to futureword-wrap instead of overflow-wrap in ie11 target mode (#2391)Support defining colors as closures even when opacity variables are not supported
Reset color opacity variable in utilities generated using closure colors
Make tailwindcss.plugin work in ESM environments for reasons
tailwindcss.plugin work in ESM environments for reasonsPrevent new dark experiment from causing third-party dark variants to inherit stacking behavior
dark experiment from causing third-party dark variants to inherit stacking behavior (#2382)Add negative spacing values to inset plugin in the extendedSpacingScale experiment
Register dark mode plugin outside of resolveConfig code path
resolveConfig code path (#2368)Fix issue where classes in escaped strings (like class=\"block\") weren't extracted properly for purging
class=\"block\") weren't extracted properly for purging (#2364)Fix issue where container padding not applied when using object syntax
Fix issue where resolveConfig didn't take into account configs added by feature flags
resolveConfig didn't take into account configs added by feature flags (#2347)Fix issue where inserting extra PurgeCSS control comments could break integrated PurgeCSS support
@apply when using the applyComplexClasses experiment (#2271)font-hairline and font-thin to font-thin and font-extralight behind standardFontWeights flag (experimental until v1.9.0) (#2333)Only warn about conservative purge mode being deprecated once per process
Fix bug where dark mode variants would cause an error if you had a plugins array in your config
plugins array in your config (#2322)Fix bug in the new font-variant-numeric utilities which broke the whole rule
This is a breaking change (although it probably won't _actually_ affect you), so to make it the default you'll have to opt-in behind the purgeLayersBy…
Tailwind CSS v1.8 is now available with a handful of new utilities, a couple new features, and an exciting new experiment 🌚!
<a name="new-features"></a>
<a name="new-font-variant-numeric-utilities"></a>
font-variant-numeric utilities (#2305)We've added a new composable API for the font-variant-numeric property, so now you can finally do the whole tabular-nums thing!
Here's what's been added:
| Class | Description |
|---|---|
normal-nums |
Reset font-variant-numeric to normal |
ordinal |
Enables the ordinal feature |
slashed-zero |
Enables the slashed-zero feature |
lining-nums |
Enables the lining-nums feature |
oldstyle-nums |
Enables the oldstyle-nums feature |
proportional-nums |
Enables the proportional-nums feature |
tabular-nums |
Enables the tabular-nums feature |
diagonal-fractions |
Enables the diagonal-fractions feature |
stacked-fractions |
Enables the stacked-fractions feature |
The exciting thing about how these are implemented is that they are composable in your HTML, so you can enable multiple font-variant-numeric features by adding multiple classes:
<p class="slashed-zero tabular-nums diagonal-fractions">12345</p>
The normal-nums class can be used to reset things, usually used at a particular breakpoint:
<p class="slashed-zero tabular-nums diagonal-fractions md:normal-nums">12345</p>
By default, only responsive variants are enabled for this new core plugin.
<a name="new-grid-alignment-utilities"></a>
We've added a bunch of new utilities for the place-items, place-content, place-self, justify-items, and justify-self properties!
Here's a complete list of what has been added:
| Core plugin | Class | CSS |
|---|---|---|
justifyItems |
justify-items-auto |
justify-items: auto |
justifyItems |
justify-items-start |
justify-items: start |
justifyItems |
justify-items-end |
justify-items: end |
justifyItems |
justify-items-center |
justify-items: center |
justifyItems |
justify-items-stretch |
justify-items: stretch |
justifySelf |
justify-self-auto |
justify-self: auto |
justifySelf |
justify-self-start |
justify-self: start |
justifySelf |
justify-self-end |
justify-self: end |
justifySelf |
justify-self-center |
justify-self: center |
justifySelf |
justify-self-stretch |
justify-self: stretch |
placeContent |
place-content-center |
place-content: center |
placeContent |
place-content-start |
place-content: start |
placeContent |
place-content-end |
place-content: end |
placeContent |
place-content-between |
place-content: space-between |
placeContent |
place-content-around |
place-content: space-around |
placeContent |
place-content-evenly |
place-content: space-evenly |
placeContent |
place-content-stretch |
place-content: stretch |
placeItems |
place-items-auto |
place-items: auto |
placeItems |
place-items-start |
place-items: start |
placeItems |
place-items-end |
place-items: end |
placeItems |
place-items-center |
place-items: center |
placeItems |
place-items-stretch |
place-items: stretch |
placeSelf |
place-self-auto |
place-self: auto |
placeSelf |
place-self-start |
place-self: start |
placeSelf |
place-self-end |
place-self: end |
placeSelf |
place-self-center |
place-self: center |
placeSelf |
place-self-stretch |
place-self: stretch |
By default, responsive variants are generated for each of these new core plugins.
<a name="new-preservehtmlelements-option-for-purge"></a>
preserveHtmlElements option for purge (#2283)Tailwind v1.8 introduces a new preserveHtmlElements option to the purge configuration that allows you to safelist all plain HTML elements, like p, blockquote, body, video, etc.
// tailwind.config.js
module.exports = {
purge: {
content: [
// Paths...
],
preserveHtmlElements: true,
},
}
This helps avoid accidentally purging things like heading elements when your source files are in a format that compiles to HTML, like markdown (since your markdown won't actually contain the string h1 anywhere).
This option is set to true by default.
<a name="new-layers-mode-for-purge"></a>
layers mode for purge (#2288)We've introduced a new layers purge mode and made it the default, deprecating the existing conservative mode.
When configured manually, it looks like this:
// tailwind.config.js
module.exports = {
purge: {
mode: 'layers',
layers: ['base', 'components', 'utilities'],
content: [
// Paths...
],
},
}
It allows you to tell Tailwind which layers it should purge (base, components, and/or utilities). The old conservative mode was the equivalent of this:
// tailwind.config.js
module.exports = {
purge: {
mode: 'layers',
layers: ['utilities'],
content: [
// Paths...
],
},
}
This is a breaking change (although it probably won't actually affect you), so to make it the default you'll have to opt-in behind the purgeLayersByDefault flag:
// tailwind.config.js
module.exports = {
future: {
purgeLayersByDefault: true,
},
// ...
}
<a name="support-configuring-variants-as-functions"></a>
Adding new variants to a core plugin is annoying right? You have to remember to list all of the existing variants, instead of just specying the new ones you want to add. Completely unacceptable!
Tailwind CSS v1.8 makes it possible to configure variants as functions so you can leverage some helpful utilities we expose to you that make it easy to extend the variant configuration instead of having to re-write the entire list:
// tailwind.config.js
module.exports = {
variants: {
opacity: ({ before }) => before(['group-hover'], 'hover'),
},
}
Read the pull request for all of the details.
<a name="dark-mode-experimental"></a>
Oh yeah I almost forgot, we added dark mode.
<div class="bg-white text-black dark:bg-black dark:text-white dark:hover:text-gray-300"></div>
It's stackable with both responsive variants and pseudo-class variants, so you can use classes like lg:dark:focus:text-white no problem.
It can be configured to use a prefers-color-scheme media query or a parent class (.dark), whichever you prefer:
module.exports = {
dark: 'media', // or 'class'
experimental {
darkModeVariant: true,
}
}
It's enabled for backgroundColor, borderColor, divideColor, textColor, gradientColorStops, and placeholderColor by default.
It's experimental right now, so enable it using the darkModeVariant experimental flag:
// tailwind.config.js
module.exports = {
experimental: {
darkModeVariant: true,
},
// ...
}
Let us know how it works for you and if there's anything we can improve before we tag it as stable!
<a name="changes"></a>
<a name="layer-rules-are-now-grouped-together"></a>
@layer rules are now grouped together (#2312)Any custom CSS defined within a @layer at-rule that matches one of Tailwind's layers is now grouped together with the corresponding Tailwind rules.
For example, this CSS:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn {
background: blue;
}
}
@layer utilities {
.align-banana {
text-align: banana;
}
}
@layer base {
h1 {
font-weight: bold;
}
}
@layer components {
.card {
border-radius: 12px;
}
}
@layer base {
p {
font-weight: normal;
}
}
@layer utilities {
.align-sandwich {
text-align: sandwich;
}
}
...conceptually becomes this:
@tailwind base;
h1 {
font-weight: bold;
}
p {
font-weight: normal;
}
@tailwind components;
.btn {
background: blue;
}
.card {
border-radius: 12px;
}
@tailwind utilities;
.align-banana {
text-align: banana;
}
.align-sandwich {
text-align: sandwich;
}
This is useful for avoiding CSS declaration order specificity issues and lets you decouple authoring order from intended render order. This is generally inline with the new @layer CSS proposal that came out shortly after we introduced this at-rule to Tailwind ourselves without knowing that existed, heh.
This is a change in behavior to how things worked before but we don't document the @layer rule outside of mentioning it in the release notes for Tailwind 1.6. I am going to be a bit bold and classify this as a bugfix, as this is how this always should have worked. Basically a zero percent chance this will break anything for anyone.
<a name="deprecations"></a>
<a name="conservative-purge-mode-deprecated-in-favor-of-layers"></a>
conservative purge mode deprecated in favor of layers (#2288)The new layers mode replaces the old conservative mode and will be the default in v2.0. You'll get a console warning until you update this value in your config file.
If you want to update without any changes in behavior, use this configuration:
// tailwind.config.js
module.exports = {
purge: {
mode: 'layers',
layers: ['utilities'],
content: [
// Paths...
],
},
}
preserveHtmlElements option for purge (#2283)layers mode for purge (#2288)font-variant-numeric utilities (#2305)place-items, place-content, place-self, justify-items, and justify-self utilities (#2306)@layer at-rules are now grouped with the corresponding @tailwind at-rule (#2312)conservative purge mode, deprecated in favor of layersFix bug where the new experimental @apply implementation broke when applying a variant class with the important option globally enabled
@apply implementation broke when applying a variant class with the important option globally enabledUpdate lodash to latest to silence security warnings
Fix bug where the new applyComplexClasses experiment didn't behave as expected with rules with multiple selectors, like .foo, .bar { color: red }
applyComplexClasses experiment didn't behave as expected with rules with multiple selectors, like .foo, .bar { color: red }@apply insensitive to whitespace in the new applyComplexClasses experiment-p flag to CLI to quickly scaffold a postcss.config.js filepostcss.config.js file@apply insensitive to whitespace in the new applyComplexClasses experimentapplyComplexClasses experiment didn't behave as expected with rules with multiple selectors, like .foo, .bar { color: red }Fix bug that prevented defining colors as closures when the gradientColorStops plugin was enabled
bg-none utility for disabling background imagesReuse generated CSS as much as possible in long-running processes instead of needlessly recalculating
Don't issue duplicate flag notices in long-running build processes
Any time we deprecate functionality or introduce new (stable) breaking changes, they will be available in Tailwind v1.x under a future property in you…
Another new Tailwind release is here! This one sort of came out of nowhere and is loaded with exciting stuff (especially down in the experiments section...)
Let's dig in!
<a name="new-features"></a>
<a name="gradients"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2176
The big one for this release — Tailwind now ships with built-in support for background gradients!
Gradients are designed with a highly composable API that lets you specify up to three color stops in one of 8 directions by default:
<div class="bg-gradient-to-r from-orange-400 via-red-500 to-pink-500">
<!-- ... -->
</div>
This is made possible by a new backgroundImage core plugin (which you can use for any background images you like!) and a new gradientColorStops core plugin.
The default configuration for these plugins looks like this:
// tailwind.config.js
module.exports = {
theme: {
backgroundImage: {
'gradient-to-t': 'linear-gradient(to top, var(--gradient-color-stops))',
'gradient-to-tr': 'linear-gradient(to top right, var(--gradient-color-stops))',
'gradient-to-r': 'linear-gradient(to right, var(--gradient-color-stops))',
'gradient-to-br': 'linear-gradient(to bottom right, var(--gradient-color-stops))',
'gradient-to-b': 'linear-gradient(to bottom, var(--gradient-color-stops))',
'gradient-to-bl': 'linear-gradient(to bottom left, var(--gradient-color-stops))',
'gradient-to-l': 'linear-gradient(to left, var(--gradient-color-stops))',
'gradient-to-tl': 'linear-gradient(to top left, var(--gradient-color-stops))',
},
gradientColorStops: (theme) => theme('colors'),
},
variants: {
backgroundImage: ['responsive'],
gradientColorStops: ['responsive', 'hover', 'focus'],
},
}
Learn more the original pull request.
<a name="new-background-clip-utilities"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2168
We've also added a new backgroundClip core plugin that you can use to control how background are rendered within an element.
It includes 4 new utilities:
| Class | CSS |
|---|---|
bg-clip-border |
background-clip: border-box |
bg-clip-padding |
background-clip: padding-box |
bg-clip-content |
background-clip: content-box |
bg-clip-text |
background-clip: text |
Combined with the new gradient features, you can use this to do cool gradient text stuff like this:
<h1 class="text-6xl font-bold">
<span class="bg-clip-text text-transparent bg-gradient-to-r from-teal-400 to-blue-500">
Greetings from Tailwind v1.7.
</span>
</h1>
Only responsive variants are enabled for the backgroundClip plugin by default:
// tailwind.config.js
module.exports = {
variants: {
backgroundClip: ['responsive'],
},
}
<a name="new-gap-utility-aliases"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2137
For some dumb reason I named the column-gap and row-gap utilities col-gap-{n} and row-gap-{n} respectively, which isn't terrible but it's not consistent with how other things in Tailwind are named.
I was finding myself getting them wrong all the time — is row-gap the gaps in a row, or the gap between rows?
Tailwind v1.7 introduces new gap-x-{n} and gap-y-{n} utilities that do the exact same thing but have names that don't suck. They make way more sense than the actual CSS names now that gap for flexbox is starting to roll out too, since flexbox has no "columns".
These utilities will replace the old ones in v2.0, but for now they both exist together.
We recommend migrating to the new names now, and disabling the old names using this feature flag:
// tailwind.config.js
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
},
// ...
}
Tailwind will issue a warning in the console to remind you that you are including deprecated classes in your build until you enable this flag.
<a name="new-contents-display-utility"></a>
contents display utilityhttps://github.com/tailwindlabs/tailwindcss/pull/2023
We've added a new contents class for the recent display: contents CSS feature.
<div class="flex">
<div><!-- ... --></div>
<!-- This container will act as a phantom container, and its children will be treated as part of the parent flex container -->
<div class="contents">
<div><!-- ... --></div>
<div><!-- ... --></div>
</div>
<div><!-- ... --></div>
</div>
Learn more about it in this great article by Rachel Andrew.
<a name="default-letter-spacing-per-font-size"></a>
https://github.com/tailwindlabs/tailwindcss/pull/1915
You can now configure a default letter-spacing value for each font-size in your tailwind.config.js theme, using a tuple syntax:
// tailwind.config.js
module.exports = {
theme: {
fontSize: {
2xl: ['24px', {
letterSpacing: '-0.01em',
}],
// Or with a default line-height as well
3xl: ['32px', {
letterSpacing: '-0.02em',
lineHeight: '40px',
}],
}
}
}
This new syntax is supported in addition to the simpler [{fontSize}, {lineHeight}] syntax that was recently introduced.
<a name="divide-border-styles"></a>
https://github.com/tailwindlabs/tailwindcss/pull/1965
We've added utilities for setting the border style on the divide utilities:
<div class="divide-y divide-dashed">
<div><!-- ... --></div>
<div><!-- ... --></div>
<div><!-- ... --></div>
<div><!-- ... --></div>
</div>
These utilities include responsive variants by default:
// tailwind.config.js
module.exports = {
variants: {
divideStyle: ['responsive'],
},
}
<a name="access-entire-config-object-from-plugins"></a>
https://github.com/tailwindlabs/tailwindcss/pull/1583
The config function passed to the plugin API now returns the entire config option when invoked with no arguments:
tailwind.plugin(function ({ config, addUtilities, /* ... */ })) {
// Returns entire config object
config()
})
<a name="define-colors-as-closures"></a>
https://github.com/tailwindlabs/tailwindcss/pull/1676
You can now define your colors as callbacks, which receive a bag of parameters you can use to generate your color value.
This is particularly useful when trying to make your custom colors work with the backgroundOpacity, textOpacity, etc. utilities
// tailwind.config.js
module.exports = {
theme: {
colors: {
primary: ({ opacityVariable }) => `rgba(var(--color-primary), var(${variable}, 1))`,
},
},
}
Currently the only thing passed through is an opacityVariable property, which contains the name of the current opacity variable (--background-opacity, --text-opacity, etc.) depending on which plugin is using the color.
<a name="deprecations"></a>
Tailwind v1.7 introduces a new feature flagging and deprecation system designed to make upgrades as painless as possible.
Any time we deprecate functionality or introduce new (stable) breaking changes, they will be available in Tailwind v1.x under a future property in your tailwind.config.js file.
Whenever there are deprecations or breaking changes available, Tailwind will warn you in the console on every build until you adopt the new changes and enable the flag in your config file:
risk - There are upcoming breaking changes: removeDeprecatedGapUtilities
risk - We highly recommend opting-in to these changes now to simplify upgrading Tailwind in the future.
risk - https://tailwindcss.com/docs/upcoming-changes
You can opt-in to a breaking change by setting that flag to true in your tailwind.config.js file:
// tailwind.config.js
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
},
}
If you'd prefer not to opt-in but would like to silence the warning, explicitly set the flag to false:
// tailwind.config.js
module.exports = {
future: {
removeDeprecatedGapUtilities: false,
},
}
We do not recommend this, as it will make upgrading to Tailwind v2.0 more difficult.
<a name="deprecated-gap-utilities"></a>
As mentioned previously, Tailwind v1.7.0 introduces new gap-x-{n} and gap-y-{n} utilities to replace the current col-gap-{n} and row-gap-{n} utilities.
By default both classes will exist, but the old utilities will be removed in Tailwind v2.0.
To migrate to the new class names, simply replace any existing usage of the old names with the new names:
- <div class="col-gap-4 row-gap-2 ...">
+ <div class="gap-x-4 gap-y-2 ...">
To opt-in to the new names now, enable the removeDeprecatedGapUtilities flag in your tailwind.config.js file:
// tailwind.config.js
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
},
}
<a name="experimental-features"></a>
Tailwind v1.7.0 introduces a new experimental feature system that allows you to opt-in to new functionality that is coming to Tailwind soon but isn't quite stable yet.
It's important to note that experimental features may introduce breaking changes, do not follow semver, and can change at any time.
If you like to live on the wild side though, you can enable all of them like so:
// tailwind.config.js
module.exports = {
experimental: 'all',
}
With that out of the way, here is some of the fun stuff we're working on that we're pumped you can finally play with...
<a name="use-apply-with-variants-and-other-complex-classes"></a>
@apply with variants and other complex classeshttps://github.com/tailwindlabs/tailwindcss/pull/2159
This is a huge one — you can finally use @apply with responsive variants, pseudo-class variants, and other complex classes!
.btn {
@apply bg-indigo hover:bg-indigo-700 sm:text-lg;
}
There are a lot of details to understand with this one, so I recommend reading the pull request to learn about how it all works.
This introduces breaking changes to how @apply worked before, so be sure to read all of the details before just flipping the switch.
To enable this feature, use the applyComplexClasses flag:
// tailwind.config.js
module.exports = {
experimental: {
applyComplexClasses: true,
},
}
<a name="new-color-palette"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2132
We've added a teaser of the new Tailwind 2.0 color palette that you can start playing with today using the uniformColorPalette flag:
// tailwind.config.js
module.exports = {
experimental: {
uniformColorPalette: true,
},
}
The idea behind the new palette is that every color at every shade has a similar perceived brightness. So you can swap indigo-600 with blue-600 and expect the same color contrast.
We do expect these colors to continue to change a lot as we iterate on them, so use these at your own risk.
<a name="extended-spacing-scale"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2141
We've added a much bigger spacing scale that includes new micro values like 0.5, 1.5, 2.5, and 3.5, as well as new large values like 72, 80, and 96, and added percentage based fractional values to the whole spacing scale (1/2, 5/6, 7/12, etc.)
You can enable the extended spacing scale using the extendedSpacingScale flag:
// tailwind.config.js
module.exports = {
experimental: {
extendedSpacingScale: true,
},
}
This is pretty stable, I would be surprised if we change this.
<a name="default-line-heights-per-font-size-by-default"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2143
We've added recommended default line-heights to every built-in font-size, which can be enabled using the defaultLineHeights flag:
// tailwind.config.js
module.exports = {
experimental: {
defaultLineHeights: true,
},
}
This is a breaking change and will impact your designs, as previously all font sizes had a default line-height of 1.5.
<a name="extended-font-size-scale"></a>
https://github.com/tailwindlabs/tailwindcss/pull/2145
We've added three new font sizes (7xl, 8xl, and 9xl) to keep up with the latest huge-as-hell-hero-text trends. They include default line-heights as well.
You can enable them under the extendedFontSizeScale flag:
// tailwind.config.js
module.exports = {
experimental: {
extendedFontSizeScale: true,
},
}
contents display utility@apply with variants and other complex classes (experimental)Fixes issue where motion-safe and motion-reduce variants didn't stack correctly with group-hover variants
motion-safe and motion-reduce variants didn't stack correctly with group-hover variantsFixes issue where @keyframes respecting the important option would break animations in Chrome
@keyframes respecting the important option would break animations in ChromeFixes an issue where animation keyframes weren't included in the build without @tailwind base
@tailwind base (#2108)There aren't supposed to be any breaking changes here, but I thought that last time too. If I _did_ break something, first person to report it gets a…
It's like Tailwind CSS v1.5 except now there's animation support, overscroll utilities, and more! 🥳
There aren't supposed to be any breaking changes here, but I thought that last time too. If I did break something, first person to report it gets a Tailwind shirt 😘
prefers-reduced-motion variantsoverscroll-behavior utilities<a name="animation-support"></a>
Tailwind CSS v1.6 adds a brand new animation core plugin, with 4 general purpose animations included out of the box:
animate-spinanimate-pinganimate-pulseanimate-bounce<button type="button" class="bg-indigo-600 ..." disabled>
<svg class="animate-spin h-5 w-5 mr-3 ..." viewBox="0 0 24 24">
<!-- ... -->
</svg>
Processing
</button>
These are completely customizable as always, using the animation and keyframes sections of your tailwind.config.js theme:
// tailwind.config.js
module.exports = {
theme: {
extend: {
animation: {
wiggle: 'wiggle 1s ease-in-out infinite',
},
keyframes: {
wiggle: {
'0%, 100%': { transform: 'rotate(-3deg)' },
'50%': { transform: 'rotate(3deg)' },
},
},
},
},
}
For more information and a live demo, read the new animation documentation. For behind the scenes details about the design rationale, check out the pull request.
<a name="new-prefers-reduced-motion-variants"></a>
prefers-reduced-motion variants (#2071)To go along with the new animation features, we've also added new motion-safe and motion-reduce variants that allow you to conditionally apply CSS based on the prefers-reduced-motion media feature.
These can be useful in conjunction with transition and animation utilities to disable problematic motion for users who are sensitive to it:
<div class="... transition duration-150 ease-in-out motion-reduce:transition-none ..."></div>
...or to explicitly opt-in to motion to make sure it's only being shown to users who haven't opted out:
<div class="... motion-safe:transition duration-150 ease-in-out ..."></div>
These can be combined with responsive variants and pseudo-class variants as well:
<!-- With responsive variants -->
<div class="sm:motion-reduce:translate-y-0"></div>
<!-- With pseudo-class variants -->
<div class="motion-reduce:hover:translate-y-0"></div>
<!-- With responsive and pseudo-class variants -->
<div class="sm:motion-reduce:hover:translate-y-0"></div>
These are currently not enabled for any utilities by default, but you can enabled them as needed in the variants section of your tailwind.config.js file:
// tailwind.config.js
module.exports = {
// ...
variants: {
translate: ['responsive', 'hover', 'focus', 'motion-safe', 'motion-reduce'],
},
}
For more details, check out the updated variants documentation.
<a name="new-overscroll-behavior-utilities"></a>
overscroll-behavior utilities (#2075)We've also added new utilities for the overscroll-behavior property.
You can use these utilities to control how "scroll chaining" works in your sites, and avoid scrolling the whole page when you reach the top or bottom of an embedded scrollable area.
<div class="overscroll-y-contain ...">
<!-- ... -->
</button>
Note that this is currently not supported in Safari, but in my opinion it's not a huge deal to treat this as a progressive enhancement anyways, since it falls back fairly gracefully.
This plugin can be configured in your tailwind.config.js file as overscrollBehavior:
// tailwind.config.js
module.exports = {
// ...
// Disabling the plugin
corePlugins: {
overscrollBehavior: false,
},
// Customizing the enabled variants
variants: {
overscrollBehavior: ['responsive', 'hover'],
},
}
<a name="generate-your-css-without-an-input-file"></a>
If you never write any custom CSS and you're sick of creating this file all the time...
@tailwind base;
@tailwind components;
@tailwind utilities;
...then I've got news for you baby — if you're using our tailwindcss CLI tool you can start depositing those 58 characters into your savings account instead of wasting them on a pointless CSS file.
The input file argument is now optional in the CLI tool, so if you don't actually need a custom CSS file, you can just write this:
npx tailwindcss build -o compiled.css
Your kids are going to be so grateful for the extra time you get to spend together ❤️
prefers-reduced-motion variantsoverscroll-behaviour utilitiesFixes issue where you could no longer use @apply with unprefixed class names if you had configured a prefix
@apply with unprefixed class names if you had configured a prefixFixes accidental breaking change where adding component variants using the old manual syntax (as recommended in the docs) stopped working
~~No breaking changes, this is a minor release and we are professionals you silly goose.~~ One accidental breaking change, fixed in v1.5.1. I take bac…
I was hoping to save v1.5.0 for something really exciting (🌘) but we needed a new feature to support the new @tailwindcss/typography plugin so h*ck it, we're dropping some new stuff on you early. Enjoy! 🥳
No breaking changes, this is a minor release and we are professionals you silly goose. One accidental breaking change, fixed in v1.5.1. I take back everything I said about being professionals. I am the one who is the silly goose.
variants supportcontainer variantsfocus-visible variantchecked variant<a name="component-variants-support"></a>
variants support (#2031)Until Tailwind CSS v1.5.0, only "utility" classes were really intended to be used with variants (like "responsive", "hover", "focus", etc.)
While these are still much more useful for utilities than any other type of class, we now support generating variants for component classes as well, like the prose classes in the new @tailwindcss/typography plugin:
<article class="prose md:prose-lg">
<!-- Content -->
</article>
You can take advantage of this feature in your own component classes by using the new variants option in the second argumant of the addComponents plugin API:
plugin(function ({ addComponents })) {
addComponents({
'.card': {
// ...
}
}, {
variants: ['responsive']
})
})
...or using the array shorthand you might be familiar with from the addUtilities API:
plugin(function ({ addComponents })) {
addComponents({
'.card': {
// ...
}
}, ['responsive'])
})
To take advantage of these feature in your custom CSS (rather than using the plugin API), you can use a new @layer directive to explicitly tell Tailwind that your styles belong to the "components" bucket:
@layer components {
@responsive {
.card {
/* ... */
}
}
}
This helps Tailwind purge your unused CSS correctly, ensuring it doesn't remove any responsive component variants when using the default "conservative" purge mode.
<a name="responsive-container-variants"></a>
container variants (#2032)Piggy-backing off of the new component variants support, the container class now supports variants!
<!-- Only lock the width at `md` sizes and above -->
<div class="md:container">
<!-- ... -->
</div>
We've enabled responsive variants by default, but if you are sick in the head you can also manually enable other variants like focus, group-hover, whatever:
// tailwind.config.js
module.exports = {
// ...
variants: {
container: ['responsive', 'focus', 'group-hover'],
},
}
<a name="new-focus-visible-variant"></a>
focus-visible variant (#1824)We've added support for the :focus-visible pseudo-class using a new focus-visible variant.
This is super useful for adding focus styles that only appear to keyboard users, and are ignored for mouse users:
<button class="focus-visible:outline-none focus-visible:shadow-outline ...">
Click me
</button>
It's not enabled for anything by default, but you can enable it in the variants section of your config file:
// tailwind.config.js
module.exports = {
// ...
variants: {
backgroundColor: ['responsive', 'hover', 'focus', 'focus-visible'],
},
}
Browser support is still pretty weak on this but getting better. In the mean time, check out the polyfill and corresponding PostCSS plugin if you'd like to use this in all browsers right away.
<a name="new-checked-variant"></a>
checked variant (#1285)We've added a new checked variant you can use to conditionally style things like checkboxes and radio buttons:
<input type="checkbox" class="bg-white checked:bg-blue-500" />
It's not enabled for anything by default, but you can enable it in the variants section of your config file:
// tailwind.config.js
module.exports = {
// ...
variants: {
backgroundColor: ['responsive', 'hover', 'focus', 'checked'],
},
}
Explicitly error when using a class as the important config option instead of just generating the wrong CSS
important config option instead of just generating the wrong CSS (https://github.com/tailwindcss/tailwindcss/commit/ad850ac49128dfcc292f0025c8c42f26bc26c735)Fix bug where the divideColor plugin was using the wrong variants in IE11 target mode
divideColor plugin was using the wrong variants in IE11 target modedivideColor plugin was using the wrong '' in IE11 target modeFix bug where target: 'browserslist' didn't work, only target: ['browserslist', {...}] did
target: 'browserslist' didn't work, only target: ['browserslist', {...}] did (https://github.com/tailwindcss/tailwindcss/commit/f5c0e301a55a189f642699ecaddc952c0487e3e8)Don't generate unnecessary CSS in color plugins when color opacity utilities are disabled
Fix issue where purge: { enabled: false } was ignored, add purge: false shorthand
purge: { enabled: false } was ignored, add purge: false shorthandImprove built-in PurgeCSS extractor to better support Haml and Slim templates
Another new minor version so soon? Merry Coronavirus 🎄😷🎄
Another new minor version so soon? Merry Coronavirus 🎄😷🎄
<a name="new-space-and-divide-layout-utilities"></a>
Tailwind v1.4 adds a new set of utilities for controlling just the alpha channel of colors:
bg-opacity-{value}text-opacity-{value}border-opacity-{value}divide-opacity-{value}placeholder-opacity-{value}These utilities compose with the existing color utilities like this:
<div class="bg-red-500 bg-opacity-25">
<!-- ... -->
</div>
All of these new utilities inherit their values from the opacity config by default but can be configured independently under the following theme keys:
backgroundOpacitytextOpacityborderOpacityplaceholderOpacitydivideOpacityLearn more in the pull request.
<a name="built-in-purgecss"></a>
Tailwind v1.4 adds a new purge option to the config for removing unused CSS without the need for configuring another tool:
// tailwind.config.js
module.exports = {
purge: [
'./src/**/*.html',
'./src/**/*.vue',
'./src/**/*.jsx',
],
theme: {},
variants: {},
plugins: [],
}
Learn more in the pull request and the updated "Controlling File Size" documentation.
<a name="ie-11-target-mode"></a>
This feature is experimental and may change outside of normal semantic versioning policies.
Recently we've been adding a lot of new features to Tailwind that aren't IE 11 compatible, and if you need to support IE 11 in your projects you have to be careful not to rely on these features by mistake.
To make this easier, we've added a new target option to the config that lets you opt-in to a new ie11 mode that disables any features that are not compatible with IE 11:
// tailwind.config.js
module.exports = {
target: 'ie11',
theme: {},
variants: {},
plugins: [],
}
Learn more in the pull request.
Fix missing unit in calc bug in space plugin (space-x-0 didn't work for example)
space-x-0 didn't work for example)fs-extra dependency to ^8.0.0 to preserve Node 8 compatibility until Tailwind 2.0fs-extra dependency to ^8.0.0 to preserve Node 8 compatibility until Tailwind 2.0space-x-0 didn't work for example)Fix bug where divide-{x/y}-0 utilities didn't work due to missing unit in calc call
divide-{x/y}-0 utilities didn't work due to missing unit in calc callFix bug where the divide-x utilities were not being applied correctly due to referencing --divide-y-reverse instead of --divide-x-reverse
divide-x utilities were not being applied correctly due to referencing --divide-y-reverse instead of --divide-x-reversespace, divideWidth, and divideColor utilitiesAdd forgotten responsive variants for space, divideWidth, and divideColor utilities
responsive variants for space, divideWidth, and divideColor utilitiesFix bug where the space-x utilities were not being applied correctly due to referencing --space-y-reverse instead of --space-x-reverse
space-x utilities were not being applied correctly due to referencing --space-y-reverse instead of --space-x-reverseWe haven't changed the default config to include default line-heights as that would be a breaking change, but this is a feature we will likely take ad…
Holy crap a new Tailwind CSS release! We've got a few new goodies in this one, and I've made sure to put the most exciting ones at the top 🚀
space and divide layout utilitiestransition-delay utilitiesgroup-focus variantcontainer classcurrent to the default color paletteinline-grid utilityflow-root display utilityclear-none utility<a name="new-space-and-divide-layout-utilities"></a>
space and divide layout utilities (#1584, #1594)Prior to Tailwind v1.3, if you wanted to add some space or a border between elements, you had to manually add the necessary margin/border to all but one of the children:
<!-- Before -->
<ul>
<li>One</li>
<li class="mt-4">Two</li>
<li class="mt-4">Three</li>
</ul>
Tailwind v1.3 introduces new space-{x/y}-{n}, divide-{x/y}-{n}, and divide-{color} utilities for controlling this at the parent level instead, simplifying this common pattern into something concise and declarative that doesn't require all of that annoying duplication:
<!-- After -->
<ul class="space-y-4">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
The space-x-{n} utilities add a left margin to all but the first element, and the space-y-{n} utilities add a top margin to all but the first element:
<!-- Horizontal stack with 8px of space between each item -->
<ul class="flex space-x-2">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<!-- Vertical stack with 16px of space between each item -->
<ul class="space-y-4">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
The space utilities inherit their configuration from the global spacing configuration by default, and include negative variations like -space-x-2 to create overlapping effects.
The divide-x-{n} utilities add a left border to all but the first element, and the divide-y-{n} utilities add a top border to all but the first element:
<!-- Horizontal list with 1px border between each item -->
<ul class="flex divide-x">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<!-- Vertical list with 1px border between each item -->
<ul class="divide-y">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
The divide utilities inherit their configuration from the borderWidth configuration, and support the default keyword (set to 1px out of the box, like with borderWidth) so you can use divide-y instead of divide-y-1.
The divide-{color} utilities are used to set the color of the dividing borders:
<!-- Vertical list with 1px blue border between each item -->
<ul class="divide-y divide-blue-500">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
We've also included space-{x/y}-reverse and divide-{x/y}-reverse utilities which can be useful if you are reversing the direction of items in a container using either flex-row-reverse or flex-col-reverse. These utilities swap left margins for right margins, top margins for bottom margins, left borders for right borders, and top borders for bottom borders to account for the items being in reverse order:
<!-- Reversed horizontal list with 8px space between each item -->
<ul class="flex flex-row-reverse space-x-2 space-x-reverse">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
There are a couple limitations of our implementation that are worth pointing out:
order propertyDespite these limitations, I think you'll still find these incredibly useful. Eventually gap will have universal support in flexbox layouts and we can all rejoice.
All of these utilities include responsive variants by default, and their values and variants can be customized using the space, divideWidth, and divideColor configuration keys respectively.
<a name="new-transition-delay-utilities"></a>
transition-delay utilities (#1462)Tailwind v1.3 introduces new delay-{amount} utilities for the transition-delay property:
<div class="transition ease-in-out duration-500 delay-1000">
<!-- ... -->
</div>
We include the same values we do for the duration-{amount} utilities and generate responsive variants by default:
// tailwind.config.js
module.exports = {
theme: {
// ...
transitionDelay: {
'75': '75ms',
'100': '100ms',
'150': '150ms',
'200': '200ms',
'300': '300ms',
'500': '500ms',
'700': '700ms',
'1000': '1000ms',
},
},
variants: {
// ...
transitionDelay: ['responsive'],
},
// ...
}
<a name="new-group-focus-variant"></a>
group-focus variant (#1577)We've added a new group-focus variant that works just like the existing group-hover variant, but for focus states.
This is useful when you want to add custom focus style to a button or link that has some nested child you want to style in a specific way, for example, changing the color of an icon inside of a button when the button is focused:
<button class="group text-gray-600 focus:bg-gray-100 focus:text-gray-700">
<svg class="h-6 w-6 text-gray-400 group-focus:text-gray-500">
<!-- ... -->
</svg>
Submit
</button>
This variant not enabled for any utilities by default, but can be enabled in the variants section of your config file.
<a name="support-for-specifying-a-default-line-height-for-each-font-size-utility"></a>
A common pattern we've run into in our own Tailwind projects is repeatedly pairing a font-size utility with a particular line-height utility, for example always using text-sm with leading-5.
Tailwind v1.3 now lets you specify a default line-height for each font-size utility in your config file, using a tuple of the form [fontSize, lineHeight]:
// tailwind.config.js
module.exports = {
theme: {
fontSize: {
// Will embed no line-height value
sm: '12px',
// Will use `font-size: 16px` and `line-height: 24px`
md: ['16px', '24px'],
},
},
}
.text-sm {
font-size: 12px;
}
.text-md {
font-size: 16px;
line-height: 24px;
}
The font-size utilities are generated before the line-height utilities in the final CSS, so you can still override the line-height for a particular font-size by simply adding a leading-{size} utility:
<!-- Will still be `line-height: 1`, even though the default line-height for `text-md` is `24px` (as per the example config above) -->
<div class="text-md leading-none"></div>
We haven't changed the default config to include default line-heights as that would be a breaking change, but this is a feature we will likely take advantage of in Tailwind 2.0 sometime in the future.
<a name="support-for-breakpoint-specific-padding-for-container-class"></a>
container class (#1398)Prior to v1.3, you could configure the container class to have built-in horizontal padding like so:
// tailwind.config.js
module.exports = {
theme: {
container: {
padding: '2rem',
},
},
}
Tailwind v1.3 enhances this functionality to allow you to specify a different amount of padding for each breakpoint:
// tailwind.config.js
module.exports = {
theme: {
container: {
padding: {
default: '1rem',
sm: '2rem',
lg: '4rem',
xl: '5rem',
},
},
},
}
<a name="added-current-to-the-default-color-palette"></a>
current to the default color palette (#1438)The default color palette now includes current for currentColor, which simplifies some situations like creating buttons where the border color should match the text color:
<!-- Before -->
<button
class="text-gray-500 hover:text-gray-700 focus:text-gray-700 border border-gray-500 hover:border-gray-700 focus:border-gray-700"
>
<!-- ... -->
</button>
<!-- Now -->
<button class="text-gray-500 hover:text-gray-700 focus:text-gray-700 border border-current">
<!-- ... -->
</button>
Since this color has been added to the default color palette, it is available for textColor, borderColor, backgroundColor, and placeholderColor utilities automatically.
<a name="new-inline-grid-utility"></a>
inline-grid utility (#1375)We've added an inline-grid utility for setting display: inline-grid. This probably should've been included in v1.2 and somehow got missed, but it's here now baby.
<span class="inline-grid grid-cols-3 col-gap-4">
<!-- ... -->
</span>
Will you ever use this? I never have, but it should still be there dammit.
<a name="new-flow-root-display-utility"></a>
flow-root display utility (#1247)We've added a new flow-root utility for display: flow-root. Never heard of it? Me neither until it was PR'd.
It behaves exactly like display: block with one magical difference: it prevents collapsing margins!
<div class="flow-root">
<!-- ... -->
</div>
You'll start to find all sorts of useful use-cases for this if you pay attention, like completely obsoleting clearfix hacks.
<a name="new-clear-none-utility"></a>
clear-none utility (#1413)This has been in the documentation for months but didn't actually exist in the framework — whoops.
It sets clear: none, which is mostly useful for resetting the clear property at different breakpoints.
<p class="clear-left md:clear-none">
<!-- ... -->
</p>
Only two people noticed it was documented but missing, so odds are you don't even care that we added this.
This is probably the most exciting feature release in the history of Tailwind, so put on your seat belts.
This is probably the most exciting feature release in the history of Tailwind, so put on your seat belts.
rounded-md utilityshadow-sm utilityshadow-xs utilityplugin and plugin.withOptions APIs<a name="css-transition-support"></a>
Tailwind now includes utilities for setting the transition-property, transition-duration, and transition-timing-function properties.
<button class="opacity-50 hover:opacity-100 transition-opacity duration-100 ease-out">...</button>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .transition-{property}
transitionProperty: {
none: 'none',
all: 'all',
default: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',
colors: 'background-color, border-color, color, fill, stroke',
opacity: 'opacity',
shadow: 'box-shadow',
transform: 'transform',
},
// .ease-{timingFunction}
transitionTimingFunction: {
linear: 'linear',
in: 'cubic-bezier(0.4, 0, 1, 1)',
out: 'cubic-bezier(0, 0, 0.2, 1)',
'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
},
// .duration-{duration}
transitionDuration: {
'75': '75ms',
'100': '100ms',
'150': '150ms',
'200': '200ms',
'300': '300ms',
'500': '500ms',
'700': '700ms',
'1000': '1000ms',
},
}
}
</details>
For more information, check out the documentation.
<a name="css-transform-support"></a>
Tailwind now includes utilities for scaling, rotating, translating, and skewing elements.
<span class="transform scale-150 rotate-45 translate-x-full origin-center"></span>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .origin-{origin}
transformOrigin: {
center: 'center',
top: 'top',
'top-right': 'top right',
right: 'right',
'bottom-right': 'bottom right',
bottom: 'bottom',
'bottom-left': 'bottom left',
left: 'left',
'top-left': 'top left',
},
// .scale-{scale}
// .scale-x-{scale}
// .scale-y-{scale}
scale: {
'0': '0',
'50': '.5',
'75': '.75',
'90': '.9',
'95': '.95',
'100': '1',
'105': '1.05',
'110': '1.1',
'125': '1.25',
'150': '1.5',
},
// .rotate-{angle}
rotate: {
'-180': '-180deg',
'-90': '-90deg',
'-45': '-45deg',
'0': '0',
'45': '45deg',
'90': '90deg',
'180': '180deg',
},
// .translate-x-{distance}
// .translate-y-{distance}
// .-translate-x-{distance}
// .-translate-y-{distance}
translate: (theme, { negative }) => ({
...theme('spacing'),
...negative(theme('spacing')),
'-full': '-100%',
'-1/2': '-50%',
'1/2': '50%',
full: '100%',
}),
// .skew-x-{amount}
// .skew-y-{amount}
skew: {
'-12': '-12deg',
'-6': '-6deg',
'-3': '-3deg',
'0': '0',
'3': '3deg',
'6': '6deg',
'12': '12deg',
},
}
}
</details>
One notable difference in how this works vs. other utilities in Tailwind is that the transform utility acts sort of like a "toggle" — you need to add that class to "enable" transforms on an element but on its own it doesn't actually apply any transforms.
You apply the actual transforms by stacking additional utilities for the types of transforms you'd like to apply, like scale-150 to scale an element to 150% of its size, or rotate-45 to rotate it 45 degrees.
To make it possible to compose multiple transforms like this, we've implemented this feature using CSS custom properties, which means transforms in Tailwind are not supported in IE11. If you need to support IE11 and would like to use transforms in your project, you'll need to write custom CSS as you would have in earlier versions of Tailwind.
For more information, check out the documentation.
<a name="css-grid-utilities"></a>
Tailwind now includes utilities for CSS Grid Layout.
<div class="grid grid-cols-2 lg:grid-cols-8 gap-6">
<div class="col-span-1 lg:col-span-3"></div>
<div class="col-span-1 lg:col-span-3"></div>
<div class="col-start-1 col-end-3 lg:col-start-4 lg:col-end-8"></div>
<div class="col-span-1 col-start-1 lg:col-span-4 lg:col-start-2"></div>
<div class="col-span-1 col-end-3 lg:col-span-6 lg:col-end-9"></div>
</div>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .gap-{spacing}, .row-gap-{spacing}, .col-gap-{spacing}
gap: theme => theme('spacing'),
// .grid-cols-{cols}
gridTemplateColumns: {
none: 'none',
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
'4': 'repeat(4, minmax(0, 1fr))',
'5': 'repeat(5, minmax(0, 1fr))',
'6': 'repeat(6, minmax(0, 1fr))',
'7': 'repeat(7, minmax(0, 1fr))',
'8': 'repeat(8, minmax(0, 1fr))',
'9': 'repeat(9, minmax(0, 1fr))',
'10': 'repeat(10, minmax(0, 1fr))',
'11': 'repeat(11, minmax(0, 1fr))',
'12': 'repeat(12, minmax(0, 1fr))',
},
// .col-{value}
gridColumn: {
auto: 'auto',
'span-1': 'span 1 / span 1',
'span-2': 'span 2 / span 2',
'span-3': 'span 3 / span 3',
'span-4': 'span 4 / span 4',
'span-5': 'span 5 / span 5',
'span-6': 'span 6 / span 6',
'span-7': 'span 7 / span 7',
'span-8': 'span 8 / span 8',
'span-9': 'span 9 / span 9',
'span-10': 'span 10 / span 10',
'span-11': 'span 11 / span 11',
'span-12': 'span 12 / span 12',
},
// .col-start-{value}
gridColumnStart: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
'13': '13',
},
// .col-end-{value}
gridColumnEnd: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
'13': '13',
},
// .grid-rows-{rows}
gridTemplateRows: {
none: 'none',
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
'4': 'repeat(4, minmax(0, 1fr))',
'5': 'repeat(5, minmax(0, 1fr))',
'6': 'repeat(6, minmax(0, 1fr))',
},
// .row-{value}
gridRow: {
auto: 'auto',
'span-1': 'span 1 / span 1',
'span-2': 'span 2 / span 2',
'span-3': 'span 3 / span 3',
'span-4': 'span 4 / span 4',
'span-5': 'span 5 / span 5',
'span-6': 'span 6 / span 6',
},
// .row-start-{value}
gridRowStart: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
},
// .row-end-{value}
gridRowEnd: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
},
}
}
</details>
By default we ship the necessary utilities to construct grids with 1–12 explicit columns and 1-6 explicit rows and place elements anywhere in that grid.
Note that the approach we've taken to supporting CSS Grid is not compatible with IE11. For building grid layouts in older browsers, we recommend using Flexbox instead of CSS Grid.
For more information, check out the documentation.
<a name="added-max-w-screen-utilities"></a>
Tailwind's default max-width scale now includes values to match your breakpoints, taking the form max-w-screen-{breakpointName}.
<div class="max-w-screen-lg">...</div>
These are useful when you need behavior similar to the container class but only for certain sizes.
<a name="added-max-w-none-utility"></a>
Tailwind's default max-width scale now includes a none value for removing any max-width constraint an element might have.
<div class="max-w-md lg:max-w-none">...</div>
<a name="added-rounded-md-utility"></a>
Tailwind's default border-radius scale now includes an md value for giving an element a 6px border radius.
<div class="rounded-md"></div>
<a name="added-shadow-sm-utility"></a>
Tailwind's default box-shadow scale now includes an sm value for giving an element a very subtle small shadow — great for giving buttons or inputs a bit of depth without being super in-your-face.
<div class="shadow-sm"></div>
For more information, check out the pull request.
<a name="added-shadow-sm-utility"></a>
Tailwind's default box-shadow scale now includes an xs value for giving an element a very subtle outline shadow, very useful for stacking with other shadows when you need a tiny bit of extra distinction from the background.
<div class="shadow-md rounded-md">
<div class="shadow-xs rounded-md">
<!-- ... -->
</div>
</div>
For more information, check out the pull request.
<a name="added-stroke-width-utilities"></a>
Tailwind now includes utilities for controlling the stroke-width property of SVG elements.
<svg class="stroke-2">...</svg>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .stroke-{width}
strokeWidth: {
'0': '0',
'1': '1',
'2': '2',
}
}
}
</details>
For more information, check out the documentation.
<a name="added-fixed-line-height-utilities"></a>
Tailwind now includes a sensible set of fixed-value line-height utilities in addition to the existing relative line-height utilities.
<svg class="leading-5">...</svg>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .leading-{size}
lineHeight: {
none: '1',
tight: '1.25',
snug: '1.375',
normal: '1.5',
relaxed: '1.625',
loose: '2',
'3': '.75rem',
'4': '1rem',
'5': '1.25rem',
'6': '1.5rem',
'7': '1.75rem',
'8': '2rem',
'9': '2.25rem',
'10': '2.5rem',
}
}
}
</details>
For more information, check out the documentation.
<a name="added-additional-display-utilities-for-table-elements"></a>
Tailwind now includes a complete set of display utilities for table elements.
<div class="table-header-group">...</div>
We've added table-caption, table-column, table-column-group, table-footer-group, table-header-group, and table-row-group.
<a name="added-box-sizing-utilities"></a>
Tailwind now includes box-border and box-content utilities for setting the box-sizing property of an element.
<div class="box-content">...</div>
These can be useful when working with third party libraries that rely on the default browser value of box-sizing: content-box, which we override in our base styles.
For more information, check out the documentation.
<a name="added-clear-utilities"></a>
Tailwind now includes clear-left, clear-right, and clear-both utilities for clearing floats using the clear property.
<div class="clear-left">...</div>
For more information, check out the documentation.
<a name="config-file-dependencies-are-now-watchable"></a>
If you are require-ing other modules inside your tailwind.config.js file, those files will now be automatically watched for changes when running a webpack/PostCSS watcher.
Previously, you'd have to restart your watcher any time you changed those files. Now those changes will be noticed automatically and your CSS will just rebuild as expected — hurray!
For more information, check out the pull request.
<a name="added-new-plugin-and-plugin-with-options-ap-is"></a>
plugin and plugin.withOptions APIs (#1268)In prior versions of Tailwind, plugins were just simple anonymous functions:
// my-plugin.js
module.exports = function ({ addUtilities, variants, theme }) {
// ...
}
While this approach still works great and is 100% supported, Tailwind v1.2 adds two new official APIs for creating plugins that allow us to support some helpful new features.
The new tailwindcss/plugin module exports a function that you can use to create a plugin like so:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function ({ addUtilities, variants, theme }) {
// ...
})
You can also use plugin.withOptions to create a plugin that accepts some additional user configuration right in the plugins section of your config:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin.withOptions(function (options) {
return function ({ addUtilities, variants, theme }) {
// ...
}
})
Previously if you designed a plugin this way, users would have to make sure to invoke your plugin in their config, even if they had no custom configuration to provide:
// tailwind.config.js
module.exports = {
plugins: [
require('plugin-with-no-options'),
require('plugin-that-has-options')(),
]
}
Now Tailwind is smart enough to invoke the function on the user's behalf, so if they don't want to provide any options, they can just require the plugin:
// tailwind.config.js
module.exports = {
plugins: [
require('plugin-with-no-options'),
require('plugin-that-has-options'),
]
}
<a name="allow-plugins-to-extend-the-user-s-config"></a>
Plugins can now extend the user's config file by providing their own configuration object as a second argument to the new plugin API:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function ({ addUtilities, variants, theme }) {
// ...
}, {
theme: {
myPluginName: {...},
},
variants: {
myPluginName: ['responsive'],
}
})
This also works using the plugin.withOptions API, just pass a function that accepts your options and returns your config:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin.withOptions(function (options) {
return function ({ addUtilities, variants, theme }) {
// ...
}
}, function (options) {
return {
theme: {
myPluginName: {...},
},
variants: {
myPluginName: ['responsive'],
}
}
})
By providing your default theme values/variants this way, users can use Tailwind's extend feature to extend your defaults just like they can with core plugins.
Add additional fixed-size line-height utilities
Remove Inter from font-sans, plan to add later under new class
font-sans, plan to add later under new classAdd system-ui to default font stack
Adds missing dependency resolve which is required for making config dependencies watchable
resolve which is required for making config dependencies watchable> Please note: This is a pre-release, which means _(although I'm not planning on it)_ these new features could change before the stable version of 1.2
Please note: This is a pre-release, which means (although I'm not planning on it) these new features could change before the stable version of 1.2.0 is released.
This is probably the most exciting feature release in the history of Tailwind, so put on your seat belts.
While v1.2.0 is in pre-release, install it using:
# Using npm
npm install tailwindcss@canary
# Using yarn
yarn add tailwindcss@canary
rounded-md utilityshadow-sm utilityplugin and plugin.withOptions APIs<a name="css-transition-support"></a>
Tailwind now includes utilities for setting the transition-property, transition-duration, and transition-timing-function properties.
<button class="opacity-50 hover:opacity-100 transition-opacity duration-100 ease-out">...</button>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .transition-{property}
transitionProperty: {
none: 'none',
all: 'all',
default: 'background-color, border-color, color, opacity, transform',
colors: 'background-color, border-color, color',
opacity: 'opacity',
transform: 'transform',
},
// .ease-{timingFunction}
transitionTimingFunction: {
linear: 'linear',
in: 'cubic-bezier(0.4, 0, 1, 1)',
out: 'cubic-bezier(0, 0, 0.2, 1)',
'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
},
// .duration-{duration}
transitionDuration: {
'75': '75ms',
'100': '100ms',
'150': '150ms',
'200': '200ms',
'300': '300ms',
'500': '500ms',
'700': '700ms',
'1000': '1000ms',
},
}
}
</details>
For more information, check out the pull request.
<a name="css-transform-support"></a>
Tailwind now includes utilities for scaling, rotating, translating, and skewing elements.
<span class="transform scale-150 rotate-45 translate-x-full origin-center"></span>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .origin-{origin}
transformOrigin: {
center: 'center',
top: 'top',
'top-right': 'top right',
right: 'right',
'bottom-right': 'bottom right',
bottom: 'bottom',
'bottom-left': 'bottom left',
left: 'left',
'top-left': 'top left',
},
// .scale-{scale}
// .scale-x-{scale}
// .scale-y-{scale}
scale: {
'0': '0',
'50': '.5',
'75': '.75',
'90': '.9',
'95': '.95',
'100': '1',
'105': '1.05',
'110': '1.1',
'125': '1.25',
'150': '1.5',
},
// .rotate-{angle}
rotate: {
'-180': '-180deg',
'-90': '-90deg',
'-45': '-45deg',
'0': '0',
'45': '45deg',
'90': '90deg',
'180': '180deg',
},
// .translate-{distance}
// .translate-x-{distance}
// .translate-y-{distance}
// .-translate-{distance}
// .-translate-x-{distance}
// .-translate-y-{distance}
translate: (theme, { negative }) => ({
...theme('spacing'),
...negative(theme('spacing')),
'-full': '-100%',
'-1/2': '-50%',
'1/2': '50%',
full: '100%',
}),
// .skew-x-{amount}
// .skew-y-{amount}
skew: {},
}
}
</details>
One notable difference in how this works vs. other utilities in Tailwind is that the transform utility acts sort of like a "toggle" — you need to add that class to "enable" transforms on an element but on its own it doesn't actually apply any transforms.
You apply the actual transforms by stacking additional utilities for the types of transforms you'd like to apply, like scale-150 to scale an element to 150% of its size, or rotate-45 to rotate it 45 degrees.
Note that while we have provided sensible defaults for scale, rotate, and translate, we do not include any default values for skew. If you'd like to add skew utilities to your project, add the values you need under the skew key in your theme.
To make it possible to compose multiple transforms like this, we've implemented this feature using CSS custom properties, which means transforms in Tailwind are not supported in IE11. If you need to support IE11 and would like to use transforms in your project, you'll need to write custom CSS as you would have in earlier versions of Tailwind.
For more information, check out the pull request.
<a name="css-grid-utilities"></a>
Tailwind now includes utilities for CSS Grid Layout.
<div class="grid grid-cols-2 lg:grid-cols-8 gap-6">
<div class="col-span-1 lg:col-span-3"></div>
<div class="col-span-1 lg:col-span-3"></div>
<div class="col-start-1 col-end-3 lg:col-start-4 lg:col-end-8"></div>
<div class="col-span-1 col-start-1 lg:col-span-4 lg:col-start-2"></div>
<div class="col-span-1 col-end-3 lg:col-span-6 lg:col-end-9"></div>
</div>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .gap-{spacing}
gap: theme => theme('spacing'),
// .row-gap-{spacing}
rowGap: {},
// .col-gap-{spacing}
columnGap: {},
// .grid-cols-{cols}
gridTemplateColumns: {
none: 'none',
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
'4': 'repeat(4, minmax(0, 1fr))',
'5': 'repeat(5, minmax(0, 1fr))',
'6': 'repeat(6, minmax(0, 1fr))',
'7': 'repeat(7, minmax(0, 1fr))',
'8': 'repeat(8, minmax(0, 1fr))',
'9': 'repeat(9, minmax(0, 1fr))',
'10': 'repeat(10, minmax(0, 1fr))',
'11': 'repeat(11, minmax(0, 1fr))',
'12': 'repeat(12, minmax(0, 1fr))',
},
// .col-{value}
gridColumn: {
auto: 'auto',
'span-1': 'span 1 / span 1',
'span-2': 'span 2 / span 2',
'span-3': 'span 3 / span 3',
'span-4': 'span 4 / span 4',
'span-5': 'span 5 / span 5',
'span-6': 'span 6 / span 6',
'span-7': 'span 7 / span 7',
'span-8': 'span 8 / span 8',
'span-9': 'span 9 / span 9',
'span-10': 'span 10 / span 10',
'span-11': 'span 11 / span 11',
'span-12': 'span 12 / span 12',
},
// .col-start-{value}
gridColumnStart: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
'13': '13',
},
// .col-end-{value}
gridColumnEnd: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
'13': '13',
},
// .grid-rows-{rows}
gridTemplateRows: {},
// .row-{value}
gridRow: {},
// .row-start-{value}
gridRowStart: {},
// .row-end-{value}
gridRowEnd: {},
}
}
</details>
By default we ship the necessary utilities to construct grids with 1–12 columns and place elements anywhere in that grid, but we don't include any default utilities for controlling rows or row placement. Those utilities are supported out of the box though, you just need to add the values you need to your config file.
Note that the approach we've taken to supporting CSS Grid is not compatible with IE11. For building grid layouts in older browsers, we recommend using Flexbox instead of CSS Grid.
For more information, check out the pull request.
<a name="new-max-w-screen-utilities"></a>
Tailwind's default max-width scale now includes values to match your breakpoints, taking the form max-w-screen-{breakpointName}.
<div class="max-w-screen-lg">...</div>
These are useful when you need behavior similar to the container class but only for certain sizes.
For more information, check out the pull request.
<a name="new-max-w-none-utility"></a>
Tailwind's default max-width scale now includes a none value for removing any max-width constraint an element might have.
<div class="max-w-md lg:max-w-none">...</div>
For more information, check out the pull request.
<a name="added-inter-to-the-default-sans-serif-font-stack"></a>
Tailwind now includes Inter as the first font family in our default sans serif font stack.
Inter is a beautiful, free, open source font created by Rasmus Andersson carefully crafted for interface design. It has a similar feel to Apple's San Francisco font, but is licensed in a way that lets you use it on all operating systems.
If you care about your end users seeing the same font no matter which operating system they are running (something you don't get when using the system font stack), Inter is without a doubt the first font I would recommend. I like to think of it as "the universal system font".
This change won't affect how your site looks at all if you aren't serving Inter to your users, but now if you do want to use Inter, all you need to do is load it on your site from the CDN:
<link href="https://rsms.me/inter/inter.css" rel="stylesheet">
This change only adds "Inter" to the font stack, it does not actually automatically import/load the font files. You can choose to serve them yourself or use a CDN link like the one mentioned above.
For users who want to continue using the system font, you don't have to do anything — the browser will continue to render the system font stack in the absence of the Inter font files.
For more information, check out the pull request.
<a name="added-rounded-md-utility"></a>
Tailwind's default border-radius scale now includes an md value for giving an element a 6px border radius.
<div class="rounded-md"></div>
For more information, check out the pull request.
<a name="added-shadow-sm-utility"></a>
Tailwind's default box-shadow scale now includes an sm value for giving an element a very subtle small shadow — great for giving buttons or inputs a bit of depth without being super in-your-face.
<div class="shadow-sm"></div>
For more information, check out the pull request.
<a name="added-stroke-width-utilities"></a>
Tailwind now includes utilities for controlling the stroke-width property of SVG elements.
<svg class="stroke-2">...</svg>
<details> <summary><strong>Expand to see the default values for these utilities</strong></summary>
// tailwind.config.js
module.exports = {
theme: {
// .stroke-{width}
strokeWidth: {
'0': '0',
'1': '1',
'2': '2',
}
}
}
</details>
For more information, check out the pull request.
<a name="added-additional-display-utilities-for-table-elements"></a>
Tailwind now includes a complete set of display utilities for table elements.
<div class="table-header-group">...</div>
We've added table-caption, table-column, table-column-group, table-footer-group, table-header-group, and table-row-group.
For more information, check out the pull request.
<a name="added-box-sizing-utilities"></a>
Tailwind now includes box-border and box-content utilities for setting the box-sizing property of an element.
<div class="box-content">...</div>
These can be useful when working with third party libraries that rely on the default browser value of box-sizing: content-box which we override in our base styles (Google Maps is a good example).
For more information, check out the pull request.
<a name="added-clear-utilities"></a>
Tailwind now includes clear-left, clear-right, and clear-both utilities for clearing floats using the clear property.
<div class="clear-left">...</div>
For more information, check out the pull request.
<a name="config-file-dependencies-are-now-watchable"></a>
If you are require-ing other modules inside your tailwind.config.js file, those files will now be automatically watched for changes when running a webpack/PostCSS watcher.
Previously, you'd have to restart your watcher any time you changed those files. Now those changes will be noticed automatically and your CSS will just rebuild as expected — hurray!
For more information, check out the pull request.
<a name="added-new-plugin-and-plugin-with-options-ap-is"></a>
plugin and plugin.withOptions APIs (#1268)In prior versions of Tailwind, plugins were just simple anonymous functions:
// my-plugin.js
module.exports = function ({ addUtilities, variants, theme }) {
// ...
}
While this approach still works great and is 100% supported, Tailwind v1.2 adds two new official APIs for creating plugins that allow us to support some helpful new features.
The new tailwindcss/plugin module exports a function that you can use to create a plugin like so:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function ({ addUtilities, variants, theme }) {
// ...
})
You can also use plugin.withOptions to create a plugin that accepts some additional user configuration right in the plugins section of your config:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin.withOptions(function (options) {
return function ({ addUtilities, variants, theme }) {
// ...
}
})
Previously if you designed a plugin this way, users would have to make sure to invoke your plugin in their config, even if they had no custom configuration to provide:
// tailwind.config.js
module.exports = {
plugins: [
require('plugin-with-no-options'),
require('plugin-that-has-options')(),
]
}
Now Tailwind is smart enough to invoke the function on the user's behalf, so if they don't want to provide any options, they can just require the plugin:
// tailwind.config.js
module.exports = {
plugins: [
require('plugin-with-no-options'),
require('plugin-that-has-options'),
]
}
<a name="allow-plugins-to-extend-the-user-s-config"></a>
Plugins can now extend the user's config file by providing their own configuration object as a second argument to the new plugin API:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function ({ addUtilities, variants, theme }) {
// ...
}, {
theme: {
myPluginName: {...},
},
variants: {
myPluginName: ['responsive'],
}
})
This also works using the plugin.withOptions API, just pass a function that accepts your options and returns your config:
// my-plugin.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin.withOptions(function (options) {
return function ({ addUtilities, variants, theme }) {
// ...
}
}, function (options) {
return {
theme: {
myPluginName: {...},
},
variants: {
myPluginName: ['responsive'],
}
}
})
By providing your default theme values/variants this way, users can use Tailwind's extend feature to extend your defaults just like they can with core plugins.
Your coding agent can read these notes before it upgrades. Set up the MCP server →