以编程方式更改CSS

时间:2015-08-12 16:57:58

标签: javascript css sass

我的单页应用程序的主要颜色是以编程方式在客户端定义的。问题是它是否在我的代码中的许多地方使用。

EG。在加载时,我(在SCSS中):

body {
  background-color: #XXXXXX;
}

.btn-primary {
  background-color: #XXXXXX;
}

.content ul li a {
  color: #XXXXXX;
  border: thin solid #XXXXXX;
  &:hover {
    background-color: #XXXXX;
    color: white;
  }
}

我需要在客户端的任何地方将#XXXXXX替换为#YYYYYY

我看到的不同选项是:

1。隔离与颜色相关的CSS,并用类

包装它

类似的东西:

body {
  background-color: #XXXXXX;
  .btn-primary {
    background-color: #XXXXXX;
  }

  .content ul li a {
    color: #XXXXXX;
    border-color: #XXXXXX;
    &:hover {
      background-color: #XXXXX;
    }
  }

  &.other-color {
    background-color: #YYYYYY;
    .btn-primary {
      background-color: #YYYYYY;
    }

    .content ul li a {
      color: #YYYYYY;
      border-color: #YYYYYY;
      &:hover {
        background-color: #YYYYYY;
      }
    }
  }
}

+ Pro 最终会有效

- Con 根本不干!

2。使用脏的JS来检查每个#XXXXXX的出现并用DOM中的#YYYYYY替换。

+ Pro 似乎对我不干净

- Con 不确定是否可行

3。使用脏的JS来检查#XXXXXX的每个出现,并用CSS文件中的#YYYYYY替换。

+专业应该完成这项工作

- Con 不确定它是否可行。并且它感觉不是正确的方法。

4。将application.css编译为application-other-color.css几次并相应地使用它。

+ Pro 非常容易实施(与其他解决方案相比)

- Con 用户需要加载不同的资产,这不是SPA的最佳选择

以前有人遇到过这个问题吗?有没有比这两个更好的解决方案?如果没有,你会建议哪一个?我错过了一些优点/缺点吗?

3 个答案:

答案 0 :(得分:3)

基本上,#1,但我会以不同的方式构建它。如果它们确实是不同的状态/类,最好将它们分开,并在语义上命名它们。

这样,例如,如果你决定.body-content--error还需要绿色文本,或者其他什么,你可以轻松编辑它。现在你只需要设置javascript来切换类,这是简单。

这实际上是非常干的代码,因为.body-content.body-content--error是同一元素的不同状态。事实上,使用下面的代码,您可以将body的类设置为class="body-content body-content--error"并继承所有.body-content CSS,只需将background-color更改为{{1} }}

.body-content--error

答案 1 :(得分:2)

CSS variables似乎是完美的解决方案:

body {
  --my-color: red;                   /* Set some value */
  background-color: var(--my-color); /* Use the value in the variable */
}
.btn-primary {
  background-color: var(--my-color); /* Use the inherited value */
}

然后,改变颜色很简单:

document.body.style.setProperty('--my-color', newColor);

document.querySelector('button').onclick = function() {
  var rndcolor = '#' + ('00000' + Math.floor(Math.random() * 256 * 256 * 256).toString(16)).slice(-6);
  document.body.style.setProperty('--my-color', rndcolor);
};
body {
  --my-color: red;
  background-color: var(--my-color);
}
.content {
  background-color: #fff;
  padding: 20px;
}
.btn-primary {
  background-color: var(--my-color);
}
.content a {
  color: var(--mycolor);
  border: thin solid var(--my-color);
}
.content a:hover {
  background-color: var(--my-color);
  color: white;
}
<div class="content">
  <button class="btn-primary">Click me to change color</button>
  <a>I have a border</a>
</div>

问题是CSS变量尚未得到广泛支持。

答案 2 :(得分:0)

由于@MattDiamant,上面描述了整个方法,但对于记录,这里是我构建的最终解决方案,我认为这非常有用。

TL; DR

我创建了一个动态mixin,我只需要调用@include variable-color($property-name);并更改<body>类,以便在任何地方更改variable-color

说明

我使用scsserb:解决方案在SCSS之前需要一个预处理器,可能是grunt,gulp等。

如果有100%的SCSS解决方案,我很想知道它。

我有一个颜色的Ruby哈希:

colors = {
  green: '#00FF00',
  blue: '#0000FF',
  red: '#FF0000'
} 

_colors.css.scss.erb中,我有:

$default-background-color: #000000;

<% colors.each do |key, value|  %>
  <%= "$#{key}: #{value};" %>
<% end %>

将在_colors.css.scss输出:

$default-background-color: black;

$green = #00FF00;
$blue = #0000FF;
$red = #FF0000;

进一步在_colors.css.scss.erb

@mixin body-prefixed-rule($property, $class-name, $color) {
  body.#{$class-name} & {
    #{$property}: $color;
  }
}

@mixin variable-color($property) {
  #{$property}: $default-background-color; // Static default color, defined above
  <% colors.each do |key, value|  %>
    <%= "@include body-prefixed-rule($property, '#{key}', $#{key});" %>
  <% end %> 
}

第二个mixin将以_colors.css.scss

输出
@mixin variable-color($property) {
  #{property}: $default-background-color; // Static default color, defined above
  @include body-prefixed-rule($property, 'green', $green);
  @include body-prefixed-rule($property, 'blue', $blue);
  @include body-prefixed-rule($property, 'red', $red);
}

所以在application.css.scss,我有:

@import '_colors';

button {
  color: white;
  @include variable-color('background-color');

  &:hover {
    background-color: white;
    @include variable-color('color');
  }
}

最终在没有mixins的SCSS中输出:

button {
  color: white;
  background-color: black;

  body.green & {
    color: white;
    background-color: green;
  }
  body.blue & {
    color: white;
    background-color: blue;
  }
  body.red & {
    color: white;
    background-color: red;
  }

  &:hover {
    color: black;
    background-color: white;

    body.green & {
      color: white;
      background-color: green;
    }
    body.blue & {
      color: white;
      background-color: blue;
    }
    body.red & {
      color: white;
      background-color: red;
    }
  }
}

因此,只需使用<body>

,我只需要将@include variable-color($property-name);的类更改为在任何地方切换背景颜色