
Product
Socket for Jira Is Now Available
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.
postcss-prefix-selector
Advanced tools
Prefix every CSS selector with a custom namespace
.a => .prefix .a
$ npm install postcss-prefix-selector
A prefix is added before most selectors. Below is an example of how CSS will be transformed by adding a prefix called .namespace.
const prefixer = require('postcss-prefix-selector')
// css to be processed
const css = fs.readFileSync("input.css", "utf8")
const out = postcss().use(prefixer({
prefix: '.namespace',
exclude: ['.c'],
})).process(css).css
/* Input */
.a, .b {
color: aqua;
}
.c {
color: coral;
}
/* Output */
.namespace .a, .namespace .b {
color: aqua;
}
.c {
color: coral;
}
Please note that global selectors (html, body, :root) cannot be prefixed so instead they will be replaced with the prefix. This behaviour can be disabled with the skipGlobalSelectors option.
/* Input */
:root { --bs-blue:#0d6efd; }
html { padding: 0; }
body { margin: 0; }
/* Output */
.namespace { --bs-blue:#0d6efd; }
.namespace { padding: 0; }
.namespace { margin: 0; }
It's also possible to customize the way prefixing is done by defining a transform function:
const out = postcss().use(prefixer({
prefix: '.namespace',
// Optional transform callback for case-by-case overrides
transform: function (prefix, selector, prefixedSelector, filePath, rule) {
if (selector === 'body') {
return 'body' + prefix;
} else {
return prefixedSelector;
}
}
})).process(css).css
/* Input */
body {
background: red;
}
/* Output */
body.namespace {
background: red;
}
Use it like you'd use any other PostCSS plugin. If you also have autoprefixer in your webpack config then make sure that postcss-prefix-selector is called first. This is needed to avoid running the prefixer twice on both standard selectors and vendor specific ones (ex: @keyframes and @webkit-keyframes).
module: {
rules: [{
test: /\.css$/,
use: [
require.resolve('style-loader'),
require.resolve('css-loader'),
{
loader: require.resolve('postcss-loader'),
options: {
postcssOptions: {
plugins: {
"postcss-prefix-selector": {
prefix: '.my-prefix',
transform(prefix, selector, prefixedSelector, filePath, rule) {
if (selector.match(/^(html|body)/)) {
return selector.replace(/^([^\s]*)/, `$1 ${prefix}`);
}
if (filePath.match(/node_modules/)) {
return selector; // Do not prefix styles imported from node_modules
}
const annotation = rule.prev();
if (annotation?.type === 'comment' && annotation.text.trim() === 'no-prefix') {
return selector; // Do not prefix style rules that are preceded by: /* no-prefix */
}
return prefixedSelector;
},
},
autoprefixer: {
browsers: ['last 4 versions']
}
}
}
}
}
]
}]
}
Following the same way of Webpack but for Vite:
import prefixer from 'postcss-prefix-selector';
import autoprefixer from 'autoprefixer';
...
export default defineConfig({
...
css: {
postcss: {
plugins: [
prefixer({
prefix: '.my-prefix',
transform(prefix, selector, prefixedSelector, filePath, rule) {
if (selector.match(/^(html|body)/)) {
return selector.replace(/^([^\s]*)/, `$1 ${prefix}`);
}
if (filePath.match(/node_modules/)) {
return selector; // Do not prefix styles imported from node_modules
}
const annotation = rule.prev();
if (annotation?.type === 'comment' && annotation.text.trim() === 'no-prefix') {
return selector; // Do not prefix style rules that are preceded by: /* no-prefix */
}
return prefixedSelector;
},
}),
autoprefixer({}) // add options if needed
],
}
},
...
});
| Name | Type | Description |
|---|---|---|
prefix | string | This string is added before every CSS selector |
exclude | string[] or RegExp[] | It's possible to avoid prefixing some selectors by passing an array of selectors |
transform | Function | In cases where you may want to use the prefix differently for different selectors, it is possible to pass in a custom transform method |
ignoreFiles | string[] or RegExp[] | List of ignored files for processing |
includeFiles | string[] or RegExp[] | List of included files for processing |
skipGlobalSelectors | boolean | When enabled, global selectors (html, body, root) won't be modified by the prefixer. Default: false. |
This project was originally created by @jongleberry and is being maintained by @RadValentin. If you have any questions, feel free to ping the latter.
Please contribute! If you have any questions or bugs, open an issue. Or, open a pull request with a fix.
This project uses Mocha. If you submit a PR, please add appropriate tests and make sure that everything is green for your branch.
MIT © 2015-2024 Jonathan Ong.
The postcss-nested package allows you to nest your CSS selectors in a way that follows the same visual hierarchy of your HTML. While it doesn't add prefixes, it helps in organizing and scoping styles in a nested manner, which can be an alternative approach to managing CSS scope.
The postcss-namespace package is another PostCSS plugin that helps in scoping CSS by adding a namespace to your selectors. It is similar to postcss-prefix-selector but focuses on adding a namespace rather than a simple prefix.
The postcss-scopify package allows you to scope your CSS by adding a specific scope to your selectors. It is similar to postcss-prefix-selector but offers more flexibility in defining the scope.
FAQs
Prefix all CSS rules with a selector
The npm package postcss-prefix-selector receives a total of 590,464 weekly downloads. As such, postcss-prefix-selector popularity was classified as popular.
We found that postcss-prefix-selector demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.