在 SCSS 中迭代主题变量文件

Iterate over theme-variable files in SCSS

我想使用主题设置文件为 WordPress 主题创建不同的 css-主题。设置(简化)如下:

/themes/_theme1.scss
/themes/_theme2.scss
/components/_file1.scss
/components/_file2.scss
/theme.scss

这个想法是通过在文档正文中添加 class 来实现简单的主题化,例如 .theme-theme1.theme-theme2。在文件 _theme#.scss 中,我想定义文本颜色、字体大小等变量。在 _file#.scss 中定义了实际样式。

我现在的问题是,如何在填充 files.scss 的同时迭代主题设置文件。

示例创意,背景颜色:

body {

###foreach themefile###
&.theme# {
    background-color: $background-color;
}
###/foreach###

}

我知道如何在生成的 CSS 文件中只有一个主题可用,但我想让所有主题都在生成的 CSS 中可用。请随意询问更多细节,因为我不确定我是否解释正确。

有没有办法通过主题文件中变量的某种 foreach 循环来创建此样式表,或者是否必须对每个主题文件使用额外的 scss-规则来完成?

使用 @import@mixin 的组合来生成样式,有点 可能。此方法应产生最少的重复代码。

下面是我们将如何设置文件。

- scss
  - themes
    - _theme1.scss
    - _theme2.scss
  - _theme.scss
  - styles.scss

一些文件的 _ 前缀阻止它们被编译成 CSS 以保持我们的构建漂亮和干净。现在让我们浏览一下文件的内容:

_theme1.scss

$theme-name: 'theme1';

$primary-color: red;
$primary-font-size: 24px; 

_theme2.scss

$theme-name: 'theme2';

$primary-color: blue;
$primary-font-size: 12px;

这是一个过于简单的例子,但应该给出了基本的想法。每个主题文件将只包含变量。

_theme.scss

@mixin themestyle() {
  body.#{$theme-name} {
    p {
      color: $primary-color;
      font-size: $primary-font-size;
    }

    .bordered {
      border: 3px solid $primary-color;
    }
  }
}

themestyle mixin 将包含每个主题的所有样式,使用 /themes/_theme*.scss 文件中的变量。 body.#{$theme-name} 将创建一个选择器,如 body.theme1body.theme2,具体取决于 $theme-name 变量的当前值。

在这个演示中,我在 p 标签上设置了样式,但这可以很容易地扩展到您站点的所有 elements/selectors。要记住的重要一点是所有样式都需要在 body.#{$theme-name} 选择器内。

现在是最后的,也是最少的 DRY 部分。 styles.scss 文件将导入每个主题文件,然后调用 themestyle mixin 为每个主题生成样式。

styles.scss

@import 'themes/theme';

/* Theme 1 Styles */
@import 'themes/theme1';
@include themestyles();

/* Theme 2 Styles */
@import 'themes/theme2';
@include themestyles();

重复的@import/@include是必需的,因为在循环或mixin中不可能@import,或者这可以进一步优化。

编译 styles.scss 后,输出将是:

/* Theme 1 Styles */
body.theme1 p {
  color: red;
  font-size: 24px; }
body.theme1 .bordered {
  border: 3px solid red; }

/* Theme 2 Styles */
body.theme2 p {
  color: blue;
  font-size: 12px; }
body.theme2 .bordered {
  border: 3px solid blue; }

现在可以通过向 body 标签添加 class 来实现这些主题,例如 <body class="theme1"><body class="theme1">

这里 Cloud9 project 显示了设置。