1

I have the following my-file.css:

.a [data-smth] { ... }
.b .c.d { ... }
.e { ... }
#f { ... }

and I want to do something like the following (pseudocode) in Node.js:

let css = readFile('my-file.css')
let prefixedCss = prefixClasses(css, 'prfx-')
writeFile(prefixedCss, 'my-prefixed-file.css')

to end up with my-prefixed-file.css:

.prfx-a [data-smth] { ... }
.prfx-b .prfx-c.prfx-d { ... }
.prfx-e { ... }
#f { ... }

I have found these npm modules:

https://github.com/vic/prefix-css (hasn't been updated in years and has issues)
https://pegjs.org/ (requires lots of low-level AST configuration)

But I was wondering whether there are better/safer solutions that have already been tested/become standard practice ?

NOTE: The above file contents was just an example. I'm looking for a way to achieve this for files whose content is completely unknown to me. So I'm looking for a "universal" solution.

Any help would be most welcome & thank you in advance! :-)

Kawd
  • 4,122
  • 10
  • 37
  • 68
  • 2
    It looks like a simple regular expression replacement would take care of that, is there any specific roadblock you're running into? – CertainPerformance Nov 07 '18 at 07:19
  • Not sure a simple RegEx on a CSS string is a safe solution as I'm looking for a universal solution (see edited OP). I'm worried that something like `replace .XXX with .prfx-XXX` could affect a `.XXX` occurrence in the file that is not necessarily a class CSS selector but maybe an [attribute] value or the value of the `content` CSS property or other. – Kawd Nov 07 '18 at 07:31
  • A context selector would not suffice? Like `.prfx .a { ... }`? And what would you expect happens to compound selectors like `#d .a[href⁼https] > .icon-link { ... }`? – connexo Nov 07 '18 at 07:49
  • No, I'm afraid it has to be a prefix for every classname used in every CSS selector in the file – Kawd Nov 07 '18 at 07:52
  • compound selectors like `#d .a[href⁼https] > .icon-link { ... }` will also have to be prefixed see my updated OP – Kawd Nov 07 '18 at 07:54
  • 1
    Did you check https://github.com/marceloucker/postcss-prefixer? – connexo Nov 07 '18 at 07:55
  • this looks promising @connexo thanks :) – Kawd Nov 07 '18 at 07:57

1 Answers1

2

You might want to check https://github.com/marceloucker/postcss-prefixer#postcss-prefixer.

postcss-prefixer

Build Status dependencies Status devDependencies Status License: MIT

PostCSS plugin to add a prefix to all css selectors classes and ids.

Usage

With PostCSS cli:

Install postcss-cli and postcss-prefixer on your project directory:

npm install postcss-cli postcss-prefixer --save-dev

and at your package.json

"scripts": {
      "postcss": "postcss input.css -u postcss-prefixer -o output.css"
}

Others

postcss([ require('postcss-prefixer')({ /* options */ }) ])

Options

prefix

Type: `string`<br>
Default: none

String to be used as prefix

ignore

Type: `array`<br>
Default: `[]`

Array of selectors to be ignored by the plugin, accepts string and regex.

Example

Example of usage with results generated by the plugin.

Code

const postcss = require('postcss');
const prefixer = require('postcss-prefixer');
const input = fs.readFileSync('path/to/file.css',  'utf-8');
const output = postcss([
  prefixer({
        prefix: 'prefix-'
        ignore: [ /selector-/, '.ignore', '#ignore' ]
    })
]).process(input);

Input:

#selector-one .example {
  /* content */
}
.selector-two .example2 {
  /* content */
}
#ignore .ignore {
  /* content */
}
#ignore .other {
  /* content */
}

Output:

#selector-one .prefix-example {
  /* content */
}
.selector-two .prefix-example2 {
  /* content */
}
#ignore .ignore {
  /* content */
}
#ignore .prefix-other {
  /* content */
}

Credits

Plugin based on postcss-class-prefix create by thompsongl.

connexo
  • 53,704
  • 14
  • 91
  • 128