Tailwind CSS + UI libraries = no conflicts ๐
April 29, 2026 ยท View on GitHub
What
Tailwind CSS plugin
Why
To avoid style conflicts (CSS collisions/interference side effects) when using Tailwind CSS with other UI libraries like Antd, Vuetify etc.
How
This plugin limits the scope of Tailwind's opinionated preflight styles to a customizable CSS selector. So you can control exactly where in the DOM to apply these base styles โ usually your own components, not third-party ones.
Version 4 is here ๐
Looking for the v3 documentation? v3 README
Version 4 is built for TailwindCSS v4 and uses the new CSS-first @plugin API โ no JavaScript config needed.
Key changes from v3:
- Configure via
@pluginin your CSS file, nottailwind.config.js - No JS imports required
- Simpler option syntax using CSS property values
โค๏ธ If you'd like to say thanks, buy me a coffee
Support/contact tiny website
Discord server for any discussions/questions/ideas/proposals โ feel free to join.
Strategies overview
Two isolation strategies are available, covering 99% of cases:
| Strategy | Description |
|---|---|
isolation-strategy: inside![]() | Everything is protected from preflight styles, except the specified Tailwind root(s). Use it when all your Tailwind-powered content lives inside some root container. |
isolation-strategy: outside![]() | Protects specific root(s) from preflight styles โ Tailwind is everywhere outside. Use it when Tailwind is everywhere, but you want to exclude some part of the DOM from preflight. |
Quick Start
1. Install
npm i -D tailwindcss-scoped-preflight
2. Replace your Tailwind import
Most projects start with a single import:
@import "tailwindcss";
This includes Tailwind's global preflight (CSS reset) โ which is exactly what this plugin replaces with a scoped version. To avoid having both global and scoped preflight in your CSS, replace the single import with granular ones that skip preflight:
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
Why not
@import "tailwindcss"? It bundles preflight that applies to*,html,bodyglobally. With this plugin you want preflight scoped to your selector โ having both defeats the purpose.
3. Add @plugin to your CSS file
3.1 Lock Tailwind preflight inside a container
Use isolation-strategy: inside when all your Tailwind-powered content is under a single root element (like .twp). Preflight styles will only apply within that container.
/* input.css */
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp;
}
With an exclusion zone (to protect third-party markup nested under .twp):
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp;
except: .no-twp;
}
| Option | Value | Description |
|---|---|---|
isolation-strategy | inside | Required. Activates the inside-container isolation mode. |
selector | CSS selector (or comma-list) | Required. The container(s) where Tailwind content lives. e.g. .twp or .twp, [twp] |
except (optional) | CSS selector | Excludes nested elements from preflight. Useful for third-party markup under .twp. |
root-styles (optional) | move to container (default) | Moves root styles (html/body/:host) to the container selector. |
add :where | Keeps root styles on root selectors but wraps them with :where so only matching items are affected. | |
ignore (optional) | Comma-separated CSS selectors | Keeps these preflight selectors untouched (skipped by the isolation strategy). e.g. html, :host, * |
remove (optional) | Comma-separated CSS selectors | Removes preflight styles for these selectors entirely. e.g. body, :before, :after |
3.2 Exclude a container from Tailwind preflight
Use isolation-strategy: outside when Tailwind is used everywhere, but you want one section of the page to be unaffected by preflight (e.g. a legacy widget or iframe content).
/* input.css */
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: outside;
selector: .no-twp;
}
With a plus selector (to re-enable preflight for Tailwind components nested inside the excluded zone):
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: outside;
selector: .no-twp;
plus: .twp;
}
| Option | Value | Description |
|---|---|---|
isolation-strategy | outside | Required. Activates the outside-container isolation mode. |
selector | CSS selector (or comma-list) | Required. The container(s) to protect from preflight. e.g. .no-twp |
plus (optional) | CSS selector | Re-enables preflight for Tailwind components nested inside the excluded zone. e.g. .twp |
ignore (optional) | Comma-separated CSS selectors | Keeps these preflight selectors untouched (skipped by the isolation strategy). |
remove (optional) | Comma-separated CSS selectors | Removes preflight styles for these selectors entirely. |
Choosing a good selector
Use a dedicated plain class name (.twp, .no-twp) or a data attribute ([data-twp]) as your container selector. Avoid selectors that contain colons (like Tailwind modifier syntax .xl:some-class) โ they require CSS escaping (\.xl\:some-class) and add unnecessary complexity.
4. Use the selector in your DOM
export function MyApp({ children }: PropsWithChildren) {
return <div className={'twp'}>{children}</div>;
}
Configuration examples
Using multiple selectors
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp, [twp];
}
Although all strategies accept multiple selectors, it's recommended to use one short selector to avoid CSS bloat โ selectors repeat many times in the generated CSS.
Keeping some preflight styles unaffected
Use ignore to pass certain preflight selectors through without modification:
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp;
ignore: html, :host, *;
}
Removing preflight styles by selector
Use remove to strip preflight styles for specific selectors entirely:
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp;
remove: body, :before, :after;
}
Still using JS config?
TailwindCSS v4 still supports JavaScript configuration via @config, though it's deprecated in favor of CSS-first configuration. This plugin works with both approaches โ choose one, not both:
| Approach | How | Recommended? |
|---|---|---|
CSS-first (@plugin) | Configure in your .css file | โ Yes |
JS config (@config) | Configure in tailwind.config.js | For SCSS or gradual migration |
Using @config with this plugin
// tailwind.config.js
import scopedPreflightStyles from 'tailwindcss-scoped-preflight';
export default {
plugins: [
scopedPreflightStyles({
isolationStrategy: 'inside',
selector: '.twp',
}),
],
};
/* input.css */
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@config "./tailwind.config.js";
All options from the inside and outside strategy tables work the same way โ pass them as object properties instead of CSS declarations.
Important: Even with
@config, use the new v4 string-based options โ not the v3 function-based API. See the migration guide for the full mapping.
Using with SCSS/Sass
Sass preprocessors parse .scss files before TailwindCSS sees them. The @plugin block syntax contains values like selector: .twp; that Sass misinterprets โ it sees .twp as the start of a decimal number and fails:
Error: Expected digit.
โท
โ selector: .twp;
โ ^
โต
Option A: Separate CSS file (recommended)
Move the @plugin directive and Tailwind imports to a plain .css file, then import it from your SCSS:
/* tailwind.css */
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp;
}
/* globals.scss */
@use "tailwind.css";
// your SCSS styles
Option B: Use @config with JS config
Use @config to configure the plugin in JavaScript โ Sass won't try to parse the plugin options:
/* globals.scss */
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@config "./tailwind.config.js";
// your SCSS styles
See the @config section above for the tailwind.config.js example.
Migration guide (v3 โ v4)
TailwindCSS v4 replaced JavaScript config files with a CSS-first API. This plugin follows the same shift โ configure via @plugin in CSS (recommended) or via @config with updated options.
Quick reference
| v3 (tailwind.config.js) | v4 (input.css) |
|---|---|
plugins: [scopedPreflightStyles({ ... })] | @plugin "tailwindcss-scoped-preflight" { ... } |
import { scopedPreflightStyles, isolateInsideOfContainer } | No JS import needed (or import scopedPreflightStyles with @config) |
isolationStrategy: isolateInsideOfContainer('.twp') | isolation-strategy: inside; selector: .twp; |
isolationStrategy: isolateOutsideOfContainer('.no-twp') | isolation-strategy: outside; selector: .no-twp; |
['.twp', '[twp]'] (array) | selector: .twp, [twp]; (comma-separated) |
{ except: '.no-twp' } | except: .no-twp; |
{ plus: '.twp' } | plus: .twp; |
{ ignore: ['html', ':host'] } | ignore: html, :host; |
{ remove: ['body'] } | remove: body; |
modifyPreflightStyles: { ... } | Not available in v4 |
Custom isolationStrategy function | Not available in v4 |
isolateForComponents | Not available in v4 โ use inside strategy instead |
Before/after: inside strategy
v3 (tailwind.config.js):
import { scopedPreflightStyles, isolateInsideOfContainer } from 'tailwindcss-scoped-preflight';
export default {
plugins: [
scopedPreflightStyles({
isolationStrategy: isolateInsideOfContainer('.twp', {
except: '.no-twp',
}),
}),
],
};
v4 (input.css):
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp;
except: .no-twp;
}
Before/after: outside strategy
v3 (tailwind.config.js):
import { scopedPreflightStyles, isolateOutsideOfContainer } from 'tailwindcss-scoped-preflight';
export default {
plugins: [
scopedPreflightStyles({
isolationStrategy: isolateOutsideOfContainer('.no-twp', {
plus: '.twp',
}),
}),
],
};
v4 (input.css):
@import "tailwindcss/theme";
@import "tailwindcss/utilities";
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: outside;
selector: .no-twp;
plus: .twp;
}
Before/after: multiple selectors
v3 (tailwind.config.js):
scopedPreflightStyles({
isolationStrategy: isolateInsideOfContainer(['.twp', '[twp]']),
})
v4 (input.css):
@plugin "tailwindcss-scoped-preflight" {
isolation-strategy: inside;
selector: .twp, [twp];
}
Dropped features
The following v3 features are not available in v4. TailwindCSS 4 moved away from JavaScript config entirely, so any feature that required a JS callback or JS-level hook cannot be supported.
| Feature | v3 Usage | Why removed |
|---|---|---|
modifyPreflightStyles | Object or function callback to alter individual CSS declarations | TW4 has no hook mechanism for JS-based style modification โ all config is CSS strings |
Custom isolationStrategy function | isolationStrategy: ({ ruleSelector }) => string | @plugin CSS blocks only accept string scalar values, not functions |
isolateForComponents | Named export, was already deprecated in v3 | Deprecated in v3; removed in v4. Use isolation-strategy: inside with root-styles: add :where for the same effect |
| Named strategy imports | import { isolateInsideOfContainer } from 'tailwindcss-scoped-preflight' | No JS config to import into โ use @plugin directive or default import with @config |

