如何根据模版动态生成css

197 阅读1分钟

使用场景如下:

开发一个弹框组件,考虑到css所占用体积不大,故将它内置到js中更加合适。由于弹框的大小都是使用rem单位的,需要根据html节点的font-size进行换算,但该font-size在不同项目中也许不一样,所以将该font-size的值作为变量,可根据需要改变弹框的rem值,也就需要根据变量生成不同的css样式。

开发栈为

  • 构建工具 webpack
  • css处理器 less

设置webpack.config.js的loader:

{
    test: /\.less$/,
    loader: 'raw-loader!extract-loader!css-loader!less-loader',
    exclude: '/node_modules/'
}

在index.js文件中:

var baseCss = require('./base.less')

可获取到经webpack的loader处理过的css字符串,然后通过模版工具类进行变量替换


  function fnTemplate(str, data){
    var regx = new RegExp(/\$fn\.(.+?)\((.*?)\)/g);

    return str.replace(regx, function(expr, fn, val){
      return data[fn](val);
    }).replace(/[\r\n]*/g,'');;

  }
  
var baseFontSize = 36;

//生成最后完整的css内容
fnTemplate(
  baseCss,
    {
      rem: function(px){
        return px.replace(/(\d+)px/,function(expr, val){
         return (val *1 / baseFontSize) + 'rem';
        });
      }
    })

在index.less文件中:

.function-rem(@px) {
  return: ~'$fn.rem('@px~')';
}

.modal-dialog{
    border-radius: rem(1px);
    text-align: center;
    width: rem(324px);
    margin: 0 auto;
    z-index: 9000;
    position:fixed;
    box-shadow: 0px 0px rem(7px) 0px rgba(0, 0, 0, 0.2);
  }

经webpack处理过后的css为这样的:

modal - dialog {
    border - radius: $fn.rem(1px);
    text - align: center;
    width: $fn.rem(324px);
    margin: 0 auto;
    z - index: 9000;
    position: fixed;
    box - shadow: 0px 0px $fn.rem(7px) 0px rgba(0, 0, 0, 0.2);
}