postcss-prefix-selector

2.1.1last stable release 2 weeks ago
Complexity Score
Low
Open Issues
N/A
Dependent Projects
143
Weekly Downloadsglobal
472,753

License

  • MIT
    • Yesattribution
    • Permissivelinking
    • Permissivedistribution
    • Permissivemodification
    • Nopatent grant
    • Yesprivate use
    • Permissivesublicensing
    • Notrademark grant

Downloads

Readme

postcss-prefix-selector

Prefix every CSS selector with a custom namespace .a => .prefix .a

Table of Contents

  • Install
  • Usage with PostCSS
  • Usage with Webpack
  • Usage with Vite
  • Options
  • Maintainer
  • Contribute
  • License

Install

$ npm install postcss-prefix-selector

Usage with PostCSS

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;
}

Usage with webpack

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']
              }
            }
          }
        }
      }
    ]
  }]
}

Usage with Vite

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
      ],
    }
  },
...
});  

Options

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.

Maintainer

This project was originally created by @jongleberry and is being maintained by @RadValentin. If you have any questions, feel free to ping the latter.

Contribute

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.

License

MIT © 2015-2024 Jonathan Ong.

Dependencies

No runtime dependency information found for this package.

CVE IssuesActive
0
Scorecards Score
3.00
Test Coverage
No Data
Follows Semver
Yes
Github Stars
177
Dependenciestotal
7
DependenciesOutdated
5
DependenciesDeprecated
1
Threat Modelling
No Data
Repo Audits
No Data

Learn how to distribute postcss-prefix-selector in your own private NPM registry

npm config set registry  https://npm.cloudsmith.com/owner/repo
Processing...
Done
npm install postcss-prefix-selector
Processing...
Done

23 Releases

NPM on Cloudsmith

Getting started with NPM on Cloudsmith is fast and easy.