针对大量主题的可维护CSS

时间:2015-06-05 18:46:43

标签: javascript html css themes

我必须为Web应用程序实现主题,用户可以在其中动态切换。设计师需要大约20种不同的字体颜色和背景颜色。有没有办法在不创建20个不同的.css文件的情况下执行此操作?这将成为可维护性的噩梦。

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

3 个答案:

答案 0 :(得分:1)

使用SASS你可以在CSS中使用变量,你只需要在1个文件中更改它,并且它应该使用更新的变量进行编译,你应该尝试使用它。

干杯

答案 1 :(得分:1)

从广义上讲,我知道在使用一个css源(可能需要或不需要多个文件)时,有两种方法可以改变网站的风格。

  1. 定义许多类.blueBorder.redBorder等并使用JavaScript,根据需要在元素上添加和删除类。
  2. 或者再次定义类并使用JavaScript,更改这些类的定义。
  3. 可以使用两种方法的混合,但我不确定为什么会这样做。

    这里使用第二种方法JSFIDDLE

    由于其选择器的强大功能,我决定使用纯JavaScript解决方案,而不是使用jQuery,这会使编码更简单(我猜)。然而,我没有写的肉。可以找到Patrick Hunlock的getCSSRule函数here。该功能的每一行都有注释。但是,由于包装问题,我之前删除了小提琴中的评论。

    该函数返回一个指向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的元素将在上面两行执行时将背景颜色更改为红色(#f00)。没有其他需要。

    注意样式表中节点的名称与CSS规则(backgroundColorbackground-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 :(得分:-1)

CSS预处理器总是赢得这里 我会避免使用带有CSS的单独样式表,只需在一个地方定义所有颜色并进行良好的评论。它会变得混乱css和大量的配色方案。 即。

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