基于CSS类的LESS条件设置LESS变量

14

我需要设置一个Less变量来匹配网站的活动主题,即每个主题具有不同的颜色。

我想根据HTML body CSS类定义的主题来设置@themeColor的正确颜色。

例如:

body.themeBlue { @themeColor: blue; }
body.themeRed { @themeColor: red; }

这样我只需要在其他Less文件中使用@themeColor变量。

有人能帮忙吗? 根据这个链接(http://www.lesscss.org/#-scope),似乎可以做到这一点,但我无法使其生效。这里出了什么问题?


1
除非您在客户端处理less文件,否则由于less文件将在服务器端编译,这是不可能的。 - Christoph
谢谢你的回答。我没有考虑到那个。 - user1687176
3个回答

24

LESS文件无法在运行时读取应用于HTML body 元素的实际类(您可能需要实现JavaScript解决方案来执行此类操作)。

如果您只想基于body类准备好所有主题CSS以供使用,则最好的方法是将所有必要的基于主题的CSS放在一个mixin中,然后在主题类下应用它。这将减少代码重复。例如:

LESS

//mixin with all css that depends on your color
.mainThemeDependentCss() {
  @contrast: lighten(@themeColor, 20%);
  h1 {color: @themeColor;}
  p {background-color: @contrast;}
}

//use the mixin in the themes
body.themeBlue {
  @themeColor: blue;
  .mainThemeDependentCss();
}

body.themeRed {
  @themeColor: red;
  .mainThemeDependentCss();
}

CSS 输出

body.themeBlue h1 {
  color: #0000ff;
}
body.themeBlue p {
  background-color: #6666ff;
}
body.themeRed h1 {
  color: #ff0000;
}
body.themeRed p {
  background-color: #ff6666;
}

针对其他涉及主题或主题化方式的答案,请参阅:


非常感谢,它有效了!这将使我写更少的代码。我不想在整个模板中重复5次代码。 - user1687176
是的,LESS和其他预处理器的主要目的是减少代码重复。 - ScottS
1
或许将@themeColor作为mixin参数传递会更好? - Aleksei Chepovoi
有没有办法使你的@themeColor变量全局化?我认为,现在它只限于mixin的范围内,这意味着你想要应用@themeColor的任何元素都需要在mixin内部。理想情况下,我们希望能够在mixin之外应用@themeColor。这可能吗? - Michael Lynch
@MichaelLynch:如果整个文件只需要一个值,那么它可以是全局的。上面的代码创建的值基于body class不同而不同,因此变量都在该body class调用的范围内。如果您使用上面的代码设置全局值,则.themeBlue.themeRed将匹配@themeColor的值(这是不可取的)。我将主题颜色依赖项封装到.mainThemeDependentCss() mixin中,以便每个类只需编写一次。如果不同的CSS文件处理body class更改(可能合并后),则可以使用全局值。 - ScottS

3

Less中的变量实际上是常量,只会被定义一次。

作用域仅在代码大括号内部生效,所以您需要将CSS嵌套在每个主题中(这意味着重复)。

这不是理想的解决方案,因为您需要做到以下几点:

body.themeBlue {
  @color: blue;
  /* your css here */
}

body.themeRed {
  @color: red;
  /* your css here AGAIN :( */
}

您可以尝试使用变量,例如:

您可以像这样使用变量:

@color: black;
@colorRed: red;
@colorBlue: blue;

h1 {
  color: @color; // black
  body.themeRed & {
    color: @colorRed; // red
  }
  body.themeBlue & {
    color: @colorBlue; // blue
  }
}

你只需要声明颜色一次,但是需要根据主题不断添加“body.themeRed”等前缀来确保颜色的正确性。

我试图写更少的代码,而不必复制任何内容,但似乎我做不到。:/ 感谢您的回答。 - user1687176

1
您实际上可以使用@import来加载您的主题!因此,common.less将包含所有默认样式,@themeColor将应用于它。
.mainThemeDependentCss() {
  //file with all themed styles
  @import 'common.less';
}

//use the mixin in the themes
body.themeBlue {
  @themeColor: blue;
  .mainThemeDependentCss();
}

body.themeRed {
  @themeColor: red;
  .mainThemeDependentCss();
}

顺便提一下,你应该避免在common.less中使用body选择器,因为它不起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接