Features
- Works with every utility (including other plugins)
- Full IntelliSense support
- First-class tailwind-merge support
- Ensures fluid type meets accessibility requirements
- Flexible enough to handle advanced use cases
Installation
Install the package
Install
fluid-tailwind
via npm.Terminal window npm install -D fluid-tailwindAdd the plugin and extractor
The custom extractor lets you use the new
~
modifier in your Tailwind classes. Note the object format forcontent
.tailwind.config.js import fluid, { extract } from 'fluid-tailwind'export default {content: {files: [/* ... */],extract},plugins: [fluid]}Use
rem
-basedscreens
andfontSize
See the limitations section for more information.
tailwind.config.js import fluid, { extract, screens, fontSize } from 'fluid-tailwind'export default {// ...theme: {screens, // Tailwind's default screens, in `rem`fontSize, // Tailwind's default font sizes, in `rem` (including line heights)extend: {screens: {xs: '20rem'}}},// ...}
Basic usage
Your browser isn't wide enough to see the full effect
<button class="bg-sky-500 ~px-4/8 ~py-2/4 ~text-sm/xl ...">Fluid button</button>
Here’s a quick overview:
- The
~
modifier makes a utility fluid - Fluid utilities scale between their start/end values when the viewport is between the start and end breakpoints
- The start and end breakpoints default to the smallest and largest screen, but they can be customized or overridden per-utility
Configuration
Custom default breakpoints
The default start/end breakpoints can be set with a tuple of length literals [start, end]
.
Either can be omitted, in which case the plugin will use your smallest and largest
breakpoint, respectively.
// ...export default { // ... theme: { /** @type {import('fluid-tailwind').FluidThemeConfig} */ fluid: ({ theme }) => ({ defaultScreens: ['20rem', theme('screens.lg')] }) }, // ...}
Fluid type accessibility checks
By default, the plugin will not generate fluid type that would fail WCAG Success Criterion 1.4.4.
You can configure this with the checkSC144
option:
// ...export default { // ... plugins: [ fluid({ checkSC144: false // default: true }) ]}
Advanced
Customize breakpoints per-utility
You can customize the start/end breakpoints for a fluid utility with
the included ~
variant. For example:
Your browser isn't wide enough to see the full effect
<h1 class="~md/lg:~text-base/4xl">Quick increase</h1>
You can omit either start or end breakpoint to use your defaults:
Set start breakpoint to md
, end breakpoint to default
<div class="~md:~text-base/4xl">
Set end breakpoint to lg
, start breakpoint to default
<div class="~/lg:~text-base/4xl">
Arbitrary start breakpoint
If you want to set an arbitrary start breakpoint with the ~
variant, you have to use
~min-[]
(just as you’d have to use min-[]
to set an arbitrary breakpoint):
Trying to use ~[]:
to set an arbitrary start breakpoint
<div class="~[20rem]/lg:~text-base/4xl">
Using ~min-[]
to set an arbitrary start breakpoint
<div class="~min-[20rem]/lg:~text-base/4xl">
Negative values
To negate fluid utilities, the dash comes after the fluid ~
modifier:
Negating a fluid utility
<div class="~-mt-3/5">
Container queries
If you have the official container query plugin
installed, you can make fluid utilities scale between the nearest @container
widths rather than screen breakpoints by using the ~@
variant:
<h1 class="~@md/lg:~text-base/4xl">Relative to container</h1>
This may look confusing if you use named containers. Sorry about that; there’s only so many ways to pass data into Tailwind. In general, when you see the fluid ~
modifier, you know the /
denotes a start/end pair.
Just like the ~
variant, both start and end containers are optional and will use your defaults if unset.
Set end container to lg
, start container to default
<div class="~@/lg:~text-base/4xl">
Custom default containers
The default containers can be set in the same way as breakpoints. Either can be omitted, in which case the plugin will use your smallest and largest container, respectively.
// ...export default { // ... theme: { /** @type {import('fluid-tailwind').FluidThemeConfig} */ fluid: ({ theme }) => ({ defaultContainers: [, theme('containers.2xl')] }) }, // ...}
Combining with media queries
To really get crazy, you can combine fluid utilities with container or media queries, as such:
Your browser isn't wide enough to see the full effect
<h1 class="~/md:~text-base/4xl lg:~lg:~text-4xl/base">Whoa!</h1>
Here’s how this works:
- We scale our font-size between
base
and4xl
between our smallest andmd
breakpoints - We scale in the opposite direction between our
lg
and largest breakpoints
Using with a custom prefix or separator
If you’re using a custom prefix
or
separator
,
you’ll need to pass them in to the extractor as well:
import fluid, { extract } from 'fluid-tailwind'
export default { prefix: 'tw-', separator: '_', content: { files: [/* ... */], extract: extract({ prefix: 'tw-', separator: '_' }) }, // ...}
<div class="~tw-text-sm/xl">
Integrations
tailwind-merge
fluid-tailwind
officially supports tailwind-merge via a plugin:
npm install --save @fluid-tailwind/tailwind-merge
For best results, include it after any other tailwind-merge plugins:
import { extendTailwindMerge } from 'tailwind-merge'import { withFluid } from '@fluid-tailwind/tailwind-merge'
export const twMerge = extendTailwindMerge(/* ... */, withFluid)
Limitations
Due to CSS restrictions, fluid utilities require the start/end values and breakpoints to be length literals (i.e. 1rem
) with the same unit.
Values with different units
<h1 class="~p-[1rem]/[18px]">
Values with different units than breakpoints
<h1 class="~text-[1rem]/[2rem]">
export default { // ... theme: { screens: { 'sm': '320px', '2xl': '1280px' } }, // ...}
Non-literal values like calc()
<h1 class="~text-base/[calc(1.5rem-2px)]">
Non-lengths like colors
<h1 class="~text-white/red-500">
Troubleshooting
Tailwind doesn’t currently provide any error reporting tools for plugins, so if a fluid utility fails, it will output an empty rule with a comment containing the reason:
.\~mt-\[10px\]\/\[1\.5rem\] /* error - Start `10px` and end `1.5rem` units don't match */ {}
You should be able to see this if you have the official IntelliSense plugin installed and hover over the class. Otherwise, you can see it if you click the location for the empty rule in your browser’s inspector.