Reputation: 23
I need to create themes with many colors using sass, but all examples I saw I have to replicate blocks of CSS using different variable names. What I want is use same name variables on different classes colors.
What I have in my mind is something like this.
//
// My regular CSS
//
.header
background-color: $color1
border-color: $color2
.menu
background-color: $color2
border-color: $color1
//
// My colors.sass could be like this
//
.color-green
$color1: green
$color2: red
.color-blue
$color1: blue
$color2: orange
What I think the compile would give me:
.color-green .header
background-color: green
border-color: red
.color-blue .header
background-color: blue
border-color: orange
.color-green .menu
background-color: red
border-color: green
.color-green .menu
background-color: orange
border-color: blue
Is this possible?
Upvotes: 2
Views: 2517
Reputation: 11
I had the same need too, then i write a loader for webpack to resolve such problem, you could check out the DEMO to see how it works, just like you expect .
This loader compile sass with different theme variables, you can register theme by sass files and javascript.
you'd create a theme folder like this:
and set webpack config:
// webpack1
module: {
loaders: [
{
test: /\.scss$/,
loader: 'vue-style-loader!css-loader!sass-loader!sass-themes-loader'
}
]
},
'sassThemes': {
themePath: "absolute path of theme folder",
//defaultTheme: "default theme name",
//excludeTheme: ["themeName", "themeName"],
//only: ["path of sass file"]
}
and then if you import a sass file,it will automatic themed:
div {
color: $text-color;
font-size: 14px;
}
will be:
div {
color: $text-color;
font-size: 14px;
}
.theme-a div {
color: 'color-a'
}
.theme-b div {
color: 'color-b'
}
.theme-c div {
color: 'color-c'
}
for more usage,you should check out DEMO
Upvotes: 1
Reputation: 23
I can't run of duplicate some code. Here is the Github with the code: https://github.com/locaweb/locawebstyle/tree/v2/source/assets/stylesheets/locastyle/layout/colors
Here is the solution explained:
I create a shared.sass, where I put all elements that I need to change the colors, example:
shared.sass
#{$theme-color}
body {
background-color: $color2;
}
p {
color: $color1;
}
And I create other files with the name of colours that I apply. This files will have the pallete of colors in variables, like this:
green.sass
$theme-color: ".color-green"
$color1: #000
$color2: #FFF
...
@import "shared"
And a colors.sass importing all files:
@import "green"
@import "shared"
What you think guys?
Upvotes: 0
Reputation: 451
I had the same need a few days ago. And I found out that in Sass, you can have a multidimensional list, so instead of constructing individual variables, you'd create one variable to hold them all, then loop over them:
$themes: news #f44f74 #f497ac, sports #5cbb00 #b2e581, entertainment #00afc4 #92d3db
@each $theme in $themes
$area: nth($theme, 1)
$colorA: nth($theme, 2)
$colorB: nth($theme, 3)
//you can use apply a class to the body so you can customize everything else easily
div.#{$area}
h1
color: $colorA
border-bottom: 2px solid $colorB
p
color: desaturate($colorA, 60%)
Have a look on this example I prepared on Codepen: http://codepen.io/renatocarvalho/pen/CxcEJ
Upvotes: 1
Reputation: 5656
I think sass mixins are the answer here.
Imo, the best way to do this is to create mixin called ex. generate_theme, and pass color as a parameter.
Something like this: [note: I use scss syntax]
@mixin generate_theme ($name: 'green', $color: green) { // pass as many colors you need...
.color-#{$name} .header {
background-color: $color;
}
.color-#{$name} .menu {
background-color: $color;
}
}
So this mixin has two parameters, but it could have more (like color palette I think?), and it has some default values (green). Parameter $name can be useful if you want to use hex values (classes like .color-#000322 wouldn't be very maintainable).
So then you just have to include your mixin like this:
@include generate_theme; // default colors
@include generate_theme('oceanlike', #000000);
so output will be:
.color-green .header {
background-color: green;
}
.color-green .menu {
background-color: green;
}
.color-oceanlike .header {
background-color: black;
}
.color-oceanlike .menu {
background-color: black;
}
Upvotes: 0
Reputation: 123397
You could make a different assignment to the same variables ($color1 and $color2) with a simple if statement, checking the value of an extra variable, e.g.
$theme: light;
@if $theme == light {
$color1: green;
$color2: red;
}
@else if $type == dark {
$color1: blue;
$color2: orange;
}
@else {
/* fallback values */
}
and for scalability I just suggest to wrap this code in a themes.scss
file, and to include it at the beginning of your main sass file. When you want to change theme, just change the value of your $theme
variable.
You can find further info about the @if directive on the official site
Upvotes: 0