【问题标题】:Maintainable CSS for large number of themes大量主题的可维护 CSS
【发布时间】:2015-06-10 17:35:40
【问题描述】:

我必须为 Web 应用程序实现主题,用户将能够在它们之间动态切换。设计师想要大约 20 种不同的字体颜色和背景颜色。有没有办法在不创建 20 个不同的 .css 文件的情况下做到这一点?那将是可维护性的噩梦。

我认为可能必须使用 JavaScript。我目前正计划将 .css 文件作为标签附加到 DOM,然后在用户更改主题时对颜色代码进行一些字符串替换。我希望找到更好的解决方案,因为这似乎是一个非常糟糕的 hack。

【问题讨论】:

  • 尼克,JavaScript 可以成为解决方案的一部分吗?如果是这样,并且您认为通过单击 Loan Calculator 下方的一个样式按钮来演示该技术,那么今晚我将给出一个答案。只使用一个样式表。
  • 我认为可能必须使用 JavaScript。我目前正计划将 .css 文件作为

标签: javascript html css themes


【解决方案1】:

一般来说,我知道在使用一个 css 源(可能需要也可能不需要多个文件)时更改网站样式的两种方法。

  1. 定义大量类 .blueBorder、.redBorder 等,并使用 JavaScript,根据需要在元素上添加和删除类。
  2. 或定义类并再次使用 JavaScript,更改这些类的定义。

可以混合使用这两种方法,但我不确定为什么要这样做。

这是使用第二种方法的JSFIDDLE。

我决定使用纯 JavaScript 解决方案,而不是使用 jQuery,因为它的选择器的强大功能会使编码变得更简单(我猜)。然而,我没有写其中的肉。可以在 here 找到由 Patrick Hunlock 编写的函数 getCSSRule。函数的每一行都有注释。但是,我只是因为包装问题而删除了 Fiddle 中的 cmets。

该函数返回一个指向 CSS 规则的指针,然后可以轻松地对其进行操作。例如:

    // get a class rule (in production code check return value for valid result)
    var r = getCSSRule('.primaryColor');
    // change its definition
    r.style.backgroundColor = "#f00";

所有分配有primaryColor 类的元素将在执行上述2 行时将其背景颜色更改为红色(#f00)。没有其他要求。

注意样式表中节点的名称与 CSS 规则不完全相同(backgroundColor 与 background-color)。我知道这里的很多人不喜欢 w3Schools.com 网站,但是在寻找样式对象参考时,我找到了一个。你可以找到它here

这里是代码:

开始 CSS 样式:

    <style type="text/css">

        #box1 {width: 50%; height: 200px; margin: 40px auto;  padding-top: 20px;}
        #box2 {width: 50%; height: 120px; margin: 20px auto 20px; padding: 10px;}
        .primaryColor {background-color: #f00;}
        .primaryBorder {border: 10px solid #000;}
        .secondaryColor {background-color: #ff0;}
        .secondaryBorder {border: 5px solid #fff;}
        .t {color: #f00;}
    </style>

HTML:

<div id="box1" class="primaryColor primaryBorder">
    <div id="box2" class="secondaryColor secondaryBorder"><p class="t">Theme Demonstration</p>
    </div>
</div>

<form style="margin: 40px auto; width:50%">
    <div role="radio" style="text-align:center" aria-checked="false">
    <input type="radio" name="theme" CHECKED value="theme1" onClick="setThemeOne()" >Theme 1
    <input type="radio" name="theme" value="theme2" onClick="setThemeTwo()" >Theme 2
    <input type="radio" name="theme" value="theme3" onClick="setThemeThree()">Theme 3
    </div>
</form>

还有好东西,JavaScript:

function getCSSRule(ruleName, deleteFlag) {
     ruleName=ruleName.toLowerCase();
     if (document.styleSheets) {
            for (var i=0; i<document.styleSheets.length; i++) {
                 var styleSheet=document.styleSheets[i];
                 var ii=0;
                 var cssRule=false;
                 do {
                        if (styleSheet.cssRules) {
                             cssRule = styleSheet.cssRules[ii];
                        } else {
                             cssRule = styleSheet.rules[ii];
                        }
                        if (cssRule)  {
                             if (cssRule.selectorText.toLowerCase()==ruleName) {
                                    if (deleteFlag=='delete') {
                                         if (styleSheet.cssRules) {
                                                styleSheet.deleteRule(ii);
                                         } else {
                                                styleSheet.removeRule(ii);
                                         }
                                         return true;
                                    } else {
                                         return cssRule;
                                    }
                             }
                        }
                        ii++;
                 } while (cssRule)
            }
     }
     return false;
}

function setThemeOne() {
    var r = getCSSRule('.primaryColor');
    r.style.backgroundColor = "#f00";
    r = getCSSRule('.primaryBorder');
    r.style.border = "10px solid #000;";
    r = getCSSRule('.secondaryColor');
    r.style.backgroundColor = "#ff0";
    r = getCSSRule('.secondaryBorder');
    r.style.border = "5px solid #fff";
    r = getCSSRule('.t');
    r.style.color = "#000";
};


function setThemeTwo() {
    var r = getCSSRule('.primaryColor');
    r.style.backgroundColor = "#ff0";
    r = getCSSRule('.primaryBorder');
    r.style.border = "10px solid #ccc;";
    r = getCSSRule('.secondaryColor');
    r.style.backgroundColor = "#f00";
    r = getCSSRule('.secondaryBorder');
    r.style.border = "5px solid #000";
    r = getCSSRule('.t');
    r.style.color = "#ccc";

};


function setThemeThree() {
    var r = getCSSRule('.primaryColor');
    r.style.backgroundColor = "#ccc";
    r = getCSSRule('.primaryBorder');
    r.style.border = "10px solid #000;";
    r = getCSSRule('.secondaryColor');
    r.style.backgroundColor = "#000";
    r = getCSSRule('.secondaryBorder');
    r.style.border = "5px solid #fff";
    r = getCSSRule('.t');
    r.style.color = "#fff";

};

兼容性说明

我已经在 IE11 和当前版本的 Chrome 中测试过这个特定示例。但是,自 2011 年左右以来,我已经在一个站点上部署了类似的代码,当时该站点支持回到 IE7 或 IE8 的浏览器(不记得了)并且没有曾经报告过一个问题。但我现在看到我确实为 Chrome 修补了getCSSRule 函数。 (对于当前版本,我不必这样做。)这是补丁:

 if (cssRule){  //If we found a rule...
   // [KT] 04/24/2012 - added condition to check for undefined selector for Chrome
if ((cssRule.selectorText != undefined) && cssRule.selectorText.toLowerCase()==ruleName)){//match rule Name?

【讨论】:

    【解决方案2】:

    使用SASS,您可以在 CSS 中使用变量,您只需在 1 个文件中更改它,它会使用更新的变量进行编译,您应该尝试一下。

    干杯

    【讨论】:

    • Sass 好,Stylus 更好。这是主观的,但我认为它更好,因为 sass 简化了 CSS,但并没有深入简化。 Stylus 真的走得很远,并且大大地简化了。用法完全一样。
    • 并且用户将能够即时更改主题?我过去使用过 SASS,但我不知道如何使用 SASS。
    • 我从来没有用过SASS,但是我用过LESS,如果SASS在这方面和LESS一样,那么你对这个问题的回答是错误的。当然,您可以在一处定义颜色并根据需要更改颜色,但最终仍会得到多个 CSS 文件。通常情况下,我不 DV,但当答案错误时,我会。如果您想提供更多详细信息并解释您的建议为何正确,我将删除我的 DV。
    【解决方案3】:

    CSS 预处理器总是在这里获胜。
    我会避免使用 css 单独的样式表,只需在一个地方定义所有颜色并提供良好的注释。它会与 css 和大量的配色方案变得混乱。 即

    /***
    RED THEME
    ***/
    .red-theme .button {}
    .red-theme a {}
    .red-theme #footer {}
    /***
    END RED THEME
    ***/
    

    【讨论】:

    • 为什么会这样?那么,您已经定义了各种颜色,现在网页的查看器如何更改主题?您的答案不完整,甚至可能是错误的。 DV。
    猜你喜欢
    • 2018-01-09
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 2011-07-21
    • 2023-04-06
    相关资源
    最近更新 更多