This is somewhat possible using the @import combo with @mixin to create styles. This method should produce minimal duplicate code.
Here we will configure the files.
- scss - themes - _theme1.scss - _theme2.scss - _theme.scss - styles.scss
The _ prefix on some files does not allow them to be compiled into CSS, so that our assembly is clean and clean. Now open 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 a simplified example, but should give a basic idea. Each theme file will contain only variables.
_theme.scss
@mixin themestyle() { body.
The themestyle themestyle will contain all the styles for each theme, using the variables from the /themes/_theme*.scss files. body.#{$theme-name} will create a selector of type body.theme1 or body.theme2 , depending on the current value of the $theme-name variable.
In this demo, I style with the p tag, but this can easily be extended to all elements / selectors for your site. It is important to remember that all styles must be inside the body.#{$theme-name} selector.
Now the last, and smallest DRY part. The styles.scss file will import each theme file and then call themestyle mixin to create styles for each theme.
styles.scss
@import 'themes/theme'; @import 'themes/theme1'; @include themestyles(); @import 'themes/theme2'; @include themestyles();
Repeatable @import/@include is required because it cannot @import inside a loop or mixin, or it can be optimized a bit more.
After compiling styles.scss output will be:
body.theme1 p { color: red; font-size: 24px; } body.theme1 .bordered { border: 3px solid red; } body.theme2 p { color: blue; font-size: 12px; } body.theme2 .bordered { border: 3px solid blue; }
Now you can implement these themes by adding a class to the body tag, for example, <body class="theme1"> or <body class="theme1"> .
Here's a Cloud9 project showing the setup.