c49817a922e0aaea51f07a07d06df234c1a12e6ef708dd17f44656c6f9855d4dfa0073fbd5f4d5c1b14f4985af87a7ec774df1b3f57ff5fc24b0a12493a9d3 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. # postcss-prefix-selector
  2. [![NPM version][npm-image]][npm-url]
  3. [![Test coverage][coveralls-image]][coveralls-url]
  4. [![License][license-image]][license-url]
  5. [![Downloads][downloads-image]][downloads-url]
  6. [![Gitpod ready-to-code][gitpod-image]][gitpod-url]
  7. > Prefix every CSS selector with a custom namespace `.a => .prefix .a`
  8. ## Table of Contents
  9. - [Install](#install)
  10. - [Usage with PostCSS](#usage-with-postcss)
  11. - [Usage with Webpack](#usage-with-webpack)
  12. - [Usage with Vite](#usage-with-vite)
  13. - [Options](#options)
  14. - [Maintainer](#maintainer)
  15. - [Contribute](#contribute)
  16. - [License](#license)
  17. ## Install
  18. ```console
  19. $ npm install postcss-prefix-selector
  20. ```
  21. ## Usage with PostCSS
  22. ```js
  23. const prefixer = require('postcss-prefix-selector')
  24. // css to be processed
  25. const css = fs.readFileSync("input.css", "utf8")
  26. const out = postcss().use(prefixer({
  27. prefix: '.some-selector',
  28. exclude: ['.c'],
  29. // Optional transform callback for case-by-case overrides
  30. transform: function (prefix, selector, prefixedSelector, filePath, rule) {
  31. if (selector === 'body') {
  32. return 'body' + prefix;
  33. } else {
  34. return prefixedSelector;
  35. }
  36. }
  37. })).process(css).css
  38. ```
  39. Using the options above and the CSS below...
  40. ```css
  41. body {
  42. background: red;
  43. }
  44. .a, .b {
  45. color: aqua;
  46. }
  47. .c {
  48. color: coral;
  49. }
  50. ```
  51. You will get the following output
  52. ```css
  53. body.some-selector {
  54. background: red;
  55. }
  56. .some-selector .a, .some-selector .b {
  57. color: aqua;
  58. }
  59. .c {
  60. color: coral;
  61. }
  62. ```
  63. ## Usage with webpack
  64. 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`).
  65. ```js
  66. module: {
  67. rules: [{
  68. test: /\.css$/,
  69. use: [
  70. require.resolve('style-loader'),
  71. require.resolve('css-loader'),
  72. {
  73. loader: require.resolve('postcss-loader'),
  74. options: {
  75. postcssOptions: {
  76. plugins: {
  77. "postcss-prefix-selector": {
  78. prefix: '.my-prefix',
  79. transform(prefix, selector, prefixedSelector, filePath, rule) {
  80. if (selector.match(/^(html|body)/)) {
  81. return selector.replace(/^([^\s]*)/, `$1 ${prefix}`);
  82. }
  83. if (filePath.match(/node_modules/)) {
  84. return selector; // Do not prefix styles imported from node_modules
  85. }
  86. const annotation = rule.prev();
  87. if (annotation?.type === 'comment' && annotation.text.trim() === 'no-prefix') {
  88. return selector; // Do not prefix style rules that are preceded by: /* no-prefix */
  89. }
  90. return prefixedSelector;
  91. },
  92. },
  93. autoprefixer: {
  94. browsers: ['last 4 versions']
  95. }
  96. }
  97. }
  98. }
  99. }
  100. ]
  101. }]
  102. }
  103. ```
  104. ## Usage with Vite
  105. Following the same way of Webpack but for Vite:
  106. ```js
  107. import prefixer from 'postcss-prefix-selector';
  108. import autoprefixer from 'autoprefixer';
  109. ...
  110. export default defineConfig({
  111. ...
  112. css: {
  113. postcss: {
  114. plugins: [
  115. prefixer({
  116. prefix: '.my-prefix',
  117. transform(prefix, selector, prefixedSelector, filePath, rule) {
  118. if (selector.match(/^(html|body)/)) {
  119. return selector.replace(/^([^\s]*)/, `$1 ${prefix}`);
  120. }
  121. if (filePath.match(/node_modules/)) {
  122. return selector; // Do not prefix styles imported from node_modules
  123. }
  124. const annotation = rule.prev();
  125. if (annotation?.type === 'comment' && annotation.text.trim() === 'no-prefix') {
  126. return selector; // Do not prefix style rules that are preceded by: /* no-prefix */
  127. }
  128. return prefixedSelector;
  129. },
  130. }),
  131. autoprefixer({}) // add options if needed
  132. ],
  133. }
  134. },
  135. ...
  136. });
  137. ```
  138. ## Options
  139. | Name | Type | Description |
  140. |-|-|-|
  141. | `prefix` | `string` | This string is added before every CSS selector |
  142. | `exclude` | `string[]` or `RegExp[]` | It's possible to avoid prefixing some selectors by passing an array of selectors |
  143. | `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 |
  144. | `ignoreFiles` | `string[]` or `RegExp[]` | List of ignored files for processing |
  145. | `includeFiles` | `string[]` or `RegExp[]` | List of included files for processing |
  146. ## Maintainer
  147. This project was originally created by [@jongleberry](https://github.com/jonathanong) and is being maintained by [@RadValentin](https://github.com/RadValentin). If you have any questions, feel free to ping the latter.
  148. ## Contribute
  149. Please contribute! If you have any questions or bugs, [open an issue](https://github.com/RadValentin/postcss-prefix-selector/issues/new). Or, open a pull request with a fix.
  150. This project uses Mocha. If you submit a PR, please add appropriate tests and make sure that everything is green for your branch.
  151. ## License
  152. [MIT](LICENSE) © 2015-2022 Jonathan Ong.
  153. [gitpod-image]: https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod
  154. [gitpod-url]: https://gitpod.io/#https://github.com/RadValentin/postcss-prefix-selector
  155. [npm-image]: https://img.shields.io/npm/v/postcss-prefix-selector.svg?style=flat-square
  156. [npm-url]: https://npmjs.org/package/postcss-prefix-selector
  157. [coveralls-image]: https://img.shields.io/coveralls/jonathanong/postcss-prefix-selector.svg?style=flat-square
  158. [coveralls-url]: https://coveralls.io/r/jonathanong/postcss-prefix-selector
  159. [license-image]: http://img.shields.io/npm/l/postcss-prefix-selector.svg?style=flat-square
  160. [license-url]: LICENSE
  161. [downloads-image]: http://img.shields.io/npm/dm/postcss-prefix-selector.svg?style=flat-square
  162. [downloads-url]: https://npmjs.org/package/postcss-prefix-selector