Tailwind CSS plugin
To avoid style conflicts (CSS collisions/interference side effects) when using Tailwind CSS with other UI libraries like Antd, Vuetify etc.
This plugin is limiting the scope of Tailwind's opinionated preflight styles to the customizable CSS selector. So you can control where exactly in DOM to apply these base styles - usually it's your own components (not the 3rd party).
Migrate from v2 | Migrate from v1
Looking for old version's documentation? v2 | v1
Starting from version 3 it provides a powerful configuration to (optionally):
- π€ precisely control CSS selectors;
- π¨ flexibly remove any preflight styles;
- π or even modify particular values of the Tailwind preflight styles (if you have some very specific conflicts).
For ease of use, there are 3 pre-bundled isolation strategies available (as named exports) that cover 99% cases:
π¨ If none of these strategies work for your case, or something isn't perfect - you can create your own strategy.
npm i tailwindcss-scoped-preflight
// tailwind.config.js
import {
scopedPreflightStyles,
isolateInsideOfContainer, // there are also isolateOutsideOfContainer and isolateForComponents
} from 'tailwindcss-scoped-preflight';
/** @type {import("tailwindcss").Config} */
const config = {
// ...
plugins: [
// ...
scopedPreflightStyles({
isolationStrategy: isolateInsideOfContainer('.twp'),
}),
],
};
exports.default = config;
export function MyApp({children}: PropsWithChildren) {
return (
<div className={'twp'}>
{children}
</div>
);
}
Sometimes you might want only specific components to be styled (nothing else) to put them together with some other UI library components (and to have them completely unaffected).
In this case isolateForComponents
strategy might be what you need.
// tailwind.config.js
import {
scopedPreflightStyles,
isolateForComponents,
} from 'tailwindcss-scoped-preflight';
/** @type {import("tailwindcss").Config} */
const config = {
// ...
plugins: [
// ...
scopedPreflightStyles({
isolationStrategy: isolateForComponents('.comp'),
}),
],
};
exports.default = config;
// MyTailwindButton.tsx
import { type PropsWithChildren } from 'react';
export function MyTailwindButton({ children }: PropsWithChildren): ReactElement {
return (
<button className={'comp'}>
{/* this button won't have a default border and background
because of Tailwind CSS preflight styles applied to the elements
with the .comp class immediately (as per the configuration).
All the other buttons around will have their original/default styles */}
{children}
</button>
);
}
scopedPreflightStyles({
isolationStrategy: isolateForComponents(
- '.comp',
+ [
+ '.comp',
+ '.twp',
+ ],
),
})
Although all the strategies allow you to specify a number of selectors - it's recommended to use one short selector to avoid CSS bloat as selectors repeat many times in the generated CSS.
scopedPreflightStyles({
isolationStrategy: isolateForComponents(
'.comp',
// every strategy provides the same options to fine tune the transformation
+ {
+ ignore: ["html", ":host", "*"],
+ },
),
})
scopedPreflightStyles({
isolationStrategy: isolateForComponents(
'.comp',
+ {
+ remove: ["body", ":before", ":after"],
+ },
),
})
isolationStrategy
option is basically a function that accepts the original CSS selector and returns the transformed one.
// tailwind.config.js
import { scopedPreflightStyles } from 'tailwindcss-scoped-preflight';
/** @type {import("tailwindcss").Config} */
const config = {
// ...
plugins: [
// ...
scopedPreflightStyles({
isolationStrategy: ({ ruleSelector, ...rest }) => {
// some selector transformation for html, :host and body rules
if (
[
'html',
':host',
'body',
].includes(ruleSelector)
) {
return `${ruleSelector} .twp`;
}
// returning an empty string or anything falsy removes the CSS rule
if (ruleSelector === '*') {
return '';
}
// and by default - transform it as per components strategy (just for example)
return isolateForComponents('.twp')({ ruleSelector, ...rest });
// Caution! Don't forget to return the value - falsy result will remove the rule
},
}),
],
};
exports.default = config;
This option allows you to hook into the preflight styles to perform some modifications like removing or changing CSS properties.
You may configure the modifications in a declarative manner (as an object) or provide a function to have more control.
scopedPreflightStyles({
isolationStrategy: isolateForComponents('.comp'), // whatever
modifyPreflightStyles: {
html: {
// removes the line-height for the html selector
'line-height': null,
// changes the font-family
'font-family': '"Open Sans", sans-serif',
},
body: {
// replaces the margin value for the body selector in preflight styles
margin: '0 4px',
// following won't have any effect as this property is not in the preflight styles
color: 'red',
},
},
})
scopedPreflightStyles({
isolationStrategy: isolateForComponents('.comp'), // whatever
modifyPreflightStyles: ({selectorSet, property, value}) => {
// let's say you want to override the font family (no matter what the rule selector is)
if (property === 'font-family' && value !== 'inherit') {
return '"Open Sans", sans-serif';
}
// or body margin
if (selectorSet.has('body') && property === 'margin') {
return '0 4px';
}
// if you want to remove some property - return null
if (selectorSet.has('html') && property === 'line-height') {
return null;
}
// to keep the property as it is - you may return the original value;
// but returning undefined would have the same effect,
// so you may just omit such default return
return value;
},
})
import {
scopedPreflightStyles,
+ isolateInsideOfContainer,
} from 'tailwindcss-scoped-preflight';
// ...
scopedPreflightStyles({
- mode: 'matched only',
- cssSelector: '.twp',
+ isolationStrategy: isolateInsideOfContainer('.twp'),
}),
Is some cases you may have to pick the isolateForComponents strategy - try which works best for you.
import {
scopedPreflightStyles,
+ isolateOutsideOfContainer,
} from 'tailwindcss-scoped-preflight';
// ...
scopedPreflightStyles({
- mode: 'except matched',
- cssSelector: '.notwp',
+ isolationStrategy: isolateOutsideOfContainer('.notwp'),
}),
import {
scopedPreflightStyles,
+ isolateInsideOfContainer,
} from 'tailwindcss-scoped-preflight';
// ...
scopedPreflightStyles({
- preflightSelector: '.twp',
- disableCorePreflight: true,
+ isolationStrategy: isolateInsideOfContainer('.twp'),
}),