【问题标题】:Dynamic scss variable meteor动态 scss 变量流星
【发布时间】:2014-04-18 04:16:03
【问题描述】:

我有一个 scss 变量 $tint-color 用于大约 100 个地方。

一旦用户登录,我想根据他们的个人资料加载颜色并替换 $tint-color 的所有用法。

到目前为止,我找到了两个不理想的解决方案:

1) Iterate through all elements 并替换相关属性。

我不断产生新元素——所以这需要反复发生。

2) 创建一个覆盖样式表,以每个元素为目标。

这将需要大量重复的代码。

有没有更好/更简单的方法?我曾考虑向 scss 中的元素添加一个类,但我不确定这是否可行。提前感谢您的帮助!

【问题讨论】:

  • 你对 Sass 没有真正的选择:必须先编译它才能发送给用户。
  • @cimmanon 是的,我明白这一点。我正在寻找问题的任何解决方案。

标签: meteor sass


【解决方案1】:

我现在正在做的是在加载配置文件后加载一个主题 css 文件。

在服务器上,我公开了一个 iron-router 路由,该路由动态替换任何出现的颜色并返回主题 css。

问题是我没有替换 scss 变量,而是替换任何出现的颜色。这是因为在执行代码时,.scss 文件已经被捆绑到服务器上的 .css 文件中。

// return a theme based on the tintColor parameter
this.route('theme', {
    where: 'server',

    action: function () {
        var files = fs.readdirSync('../client');

        // find the css file (not the .map file)
        var cssFile = _(files).find(function (fileName) {
            return fileName.indexOf('.css') > 0 && fileName.indexOf('.map') < 0;
        });

        var style = fs.readFileSync('../client/' + cssFile, 'utf8');

        // remove comments (cannot have them for minification)
        style = style.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '');

        // replace the default tint-color with the dynamic color
        style = style.replace(/8cb850/g, this.params.tintColor);

        // minify css
        if (Settings.isProduction()) {
            // from the minifiers package
            style = CssTools.minifyCss(style);
        }

        this.response.writeHead(200, {'Content-Type': 'text/css'});
        this.response.end(style);
    }
});

更新:我用 scss 变量生成它。

Theme.compile = function (tintColor) {
    var dirName = path.dirname(styleFile);

    var styles = fs.readFileSync(styleFile, 'utf8');

    //replace default theme with dynamic theme
    var theme = '$tint-color: #' + tintColor + ';' + '\n';
    styles = styles.replace('@import "app/theme.scssimport";', theme);

    var options = {
        data: styles,
        sourceComments: 'map',
        includePaths: [dirName] // for @import
    };

    var css = sass.renderSync(options);

    // minify css
    if (Settings.isProduction()) {
        // remove comments -- cannot have them for minification
        css = css.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '');

        // Use CssTools from the minifiers package
        css = CssTools.minifyCss(css);
    }

    return css;
};

如果您这样做,请确保将 scss 文件作为资产添加到包中,example here

【讨论】:

    【解决方案2】:

    在您的原始 css 中设置基本的 $tint-color。

    然后使用流星发送带有所选用户色调的内联 CSS。

    示例:

    .tint {
      background-color: USER-TINT;
      color: USER-TINT;
    }
    

    这样您就可以缓存原始 css 文件并节省大量传输!

    【讨论】:

    • 您是否建议在服务器上生成覆盖样式表?
    • @jonperl,是和不是。您应该始终尝试将文件数量保持在最低限度。在这种情况下,我要么使用 JS 注入所需的自定义 CSS 颜色,要么使用流星优秀的模板引擎来呈现自定义样式。这样,您可以在需要时随时更新它,而无需将整个生成的样式表发送给客户端。我希望这可以解决问题,我不是最擅长解释的东西!如果您想进一步讨论,请随时与我联系!
    • 感谢您的进一步解释。这种方法的问题在于,我在大约 30% 的选择器中使用了 tint-color。这将需要大量模板特定的逻辑,对于代码复杂性,我希望避免这种逻辑。由于第一次下载后css会被缓存,所以我不太关心第一次初始开销。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 2020-06-22
    • 2014-10-22
    • 2021-05-11
    • 2019-12-10
    • 2020-01-08
    • 1970-01-01
    相关资源
    最近更新 更多