Iterate over theme-variable files in SCSS

╄→尐↘猪︶ㄣ 提交于 2019-12-13 06:37:38

问题


I want to create different css-themes for a WordPress theme by using theme setup files. The setup (simplified) would be as following:

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

The idea is to enable easy theming by adding a class to the body of the document like .theme-theme1 or .theme-theme2. In the files _theme#.scss I want to define variables like text colour, font sizes and so on. In _file#.scss the actual styles are defined.

My question now is, how to iterate over the theme setup files while filling up the files.scss.

Sample idea, Background colour:

body {

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

}

I know how to do this with only one theme available in the resulting CSS file, but I want to make ALL themes available in the resulting CSS. Feel free to ask more details as I am not sure if I explain me right.

Is there a way to create this stylesheet via some kind of foreach loops through variables in theme files or does it have to be done with extra scss-rules per theme file?


回答1:


This is somewhat possible using a combo of @import with a @mixin to generate the styles. This method should produce minimal repeated code.

Here's how we'll setup the files.

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

The _ prefix on some of the files prevent them from being compiled into CSS to keep our build nice and clean. Now let's go through the contents of the files:

_theme1.scss

$theme-name: 'theme1';

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

_theme2.scss

$theme-name: 'theme2';

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

This is an oversimplified example but should give the basic idea. Each theme file will contain only variables.

_theme.scss

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

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

The themestyle mixin will contain all the styles for each theme, using the variables from the /themes/_theme*.scss files. The body.#{$theme-name} will create a selector like body.theme1 or body.theme2, depending on the current value of the $theme-name variable.

In this demo I'm styling on a p tag but this could easily be extended to all elements/selectors for your site. The important thing to remember is all styles need to be inside the body.#{$theme-name} selector.

Now the final, and least DRY part. The styles.scss file will import each theme file then call the themestyle mixin to generate the styles for each theme.

styles.scss

@import 'themes/theme';

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

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

The repeated @import/@include is required because it's not possible to @import within a loop or mixin, or this could be optimized a bit more.

Once styles.scss is compiled the output will be:

/* 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; }

These themes can now be implemented by adding a class to the body tag, like <body class="theme1"> or <body class="theme1">.

Here's a Cloud9 project showing the setup.



来源:https://stackoverflow.com/questions/41791461/iterate-over-theme-variable-files-in-scss

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!