此页面需要javascript支持,请在浏览器中启用javascript

postcss-custom-property-prefixer

prefixer
postcss
plugin
css
custom
property
共708个字,阅读时间 4 分钟
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://icebreaker.top/articles/2023/10/13-postcss-custom-property-prefixer

postcss-custom-property-prefixer

Add prefix to your css custom-property

Usage

<npm/yarn/pnpm> i -D postcss-custom-property-prefixer

Then register this plugin into your postcss.config.js:

module.exports = {
  plugins: {
    // ...
    'postcss-custom-property-prefixer': {
      // prefix option must be passed! 
      prefix: 'ice-'
    }
    // ...
  }
}

Demo

.a {
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1));
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1));
  --tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1));
}

Will be transformed to:

.a {
  --ice-tab-color: hsl(var(--ice-bc) / var(--ice-tw-text-opacity, 1));
  --ice-tab-bg: hsl(var(--ice-b1) / var(--ice-tw-bg-opacity, 1));
  --ice-tab-border-color: hsl(var(--ice-b3) / var(--ice-tw-bg-opacity, 1));
}

Not right? Yes! Default this plugin will transform all css custom property!

If you want to ignore some custom properties like --tw-*, you should pass some ignore* options, See Below!

Use with Tailwindcss

Css nodes are generated by tailwindcss, because it's custom property all start with '--tw-', so you can pass options like below.

    'postcss-custom-property-prefixer': {
      // your custom prefix
      prefix: 'ice-',
      ignoreValueCustomProperty(cp, decl) {
        // ignore value
        return cp.startsWith('--tw-')
      },
      ignoreProp(decl) {
        // ignore prop
        return decl.prop.startsWith('--tw-')
      }
    }

Options

ignoreValueCustomProperty

plugin options:

    'postcss-custom-property-prefixer': {
      prefix: 'ice-',
      ignoreValueCustomProperty(cp) {
        return cp.startsWith('--tw-')
      }
    }

Before:

.a {
  /*                              ⬇ --tw-* */
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1));
  /*                            ⬇ --tw-* */
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1));
  /*                                      ⬇ --tw-* */
  --tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1));
}

After:

.a {
  --ice-tab-color: hsl(var(--ice-bc) / var(--tw-text-opacity, 1));
  --ice-tab-bg: hsl(var(--ice-b1) / var(--tw-bg-opacity, 1));
  --ice-tab-border-color: hsl(var(--ice-b3) / var(--tw-bg-opacity, 1));
}

See! All css decl's value's custom properties which start with --tw- are ignored!

ignoreDecl

This option will ignore the whole decl!

    'postcss-custom-property-prefixer': {
      prefix: 'ice-',
      ignoreDecl(decl) {
        return decl.prop === '--tab-color' || decl.value.includes('hsl(var(--b1)')
      },
      ignoreValueCustomProperty(cp) {
        return cp.startsWith('--tw-')
      }
    }

Before:

.a {
  /* prop === --tab-color , this decl will be ignored */
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1)); 
  /* value.includes('hsl(var(--b1)') , this will be ignored */
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1)); 
  /* will be transformed */
  --tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1)); 
}

After:

.a {
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1));
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1));
  --ice-tab-border-color: hsl(var(--ice-b3) / var(--tw-bg-opacity, 1));
}

ignoreProp

    'postcss-custom-property-prefixer': {
      prefix: 'ice-',
      ignoreProp(decl) {
        return decl.prop === '--tab-color'
      },
      ignoreValueCustomProperty(cp) {
        return cp.startsWith('--tw-')
      }
    }

Before:

.a {
  /* ⬇ only ignore the prop , not value ⬇ */
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1)); 
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1)); 
  --tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1)); 
}

After:

.a {
  /* ⬇ target prop */
  --tab-color: hsl(var(--ice-bc) / var(--tw-text-opacity, 1));
  --ice-tab-bg: hsl(var(--ice-b1) / var(--tw-bg-opacity, 1));
  --ice-tab-border-color: hsl(var(--ice-b3) / var(--tw-bg-opacity, 1));
}

ignoreValue

    'postcss-custom-property-prefixer': {
      prefix: 'ice-',
      ignoreValue(decl) {
        return decl.value.includes('hsl(var(--b3)')
      },
      ignoreValueCustomProperty(cp) {
        return cp.startsWith('--tw-')
      }
    }

Before:

.a {
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1)); 
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1));  
  /*                       ⬇ target value , ignored*/
  --tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1));
}

After:

.a {
  --ice-tab-color: hsl(var(--ice-bc) / var(--tw-text-opacity, 1));
  --ice-tab-bg: hsl(var(--ice-b1) / var(--tw-bg-opacity, 1));
  --ice-tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1));
}

prefix

Type: String|PrefixFunction, The prefix will be add to all custom property!

export type PrefixFunction = (decl: Declaration, target: 'prop' | 'value') => string
    'postcss-custom-property-prefixer': {
      prefix: (decl,target)=>{
        if (target === 'prop' && decl.prop.startsWith('--bg-')) {
          return 'aaa-'
        }
        if (target === 'value' && decl.prop.startsWith('--text-')) {
          return 'bbb-'
        }
        return ''
      },
    }

Before:

.a {
  --bg-red: hsl(var(--text-red-100));
  --text-red: hsl(var(--text-red-500));
}

After:

.a {
  --aaa-bg-red: hsl(var(--text-red-100));
  --text-red: hsl(var(--bbb-text-red-500));
}

propPrefix

Type: Same as prefix

you can pass different prefix to prop and value:

    'postcss-custom-property-prefixer': {
      prefix: 'ice-',
      propPrefix: 'xx-',
      ignoreValueCustomProperty(cp) {
        return cp.startsWith('--tw-')
      }
    }
.a {
  --tab-color: hsl(var(--bc) / var(--tw-text-opacity, 1)); 
  --tab-bg: hsl(var(--b1) / var(--tw-bg-opacity, 1));  
  --tab-border-color: hsl(var(--b3) / var(--tw-bg-opacity, 1)); 
}

After:

.a {
  --xx-tab-color: hsl(var(--ice-bc) / var(--tw-text-opacity, 1));
  --xx-tab-bg: hsl(var(--ice-b1) / var(--tw-bg-opacity, 1));
  --xx-tab-border-color: hsl(var(--ice-b3) / var(--tw-bg-opacity, 1));
}

transformProp

Boolean: whether transform css decl's prop, default: true

transformValue

Boolean: whether transform css decl's value, default: true

License

MIT License © 2023-PRESENT sonofmagic