Is it possible to have a partial named class like this
.theme-color- {
&yellow {
color: yellow
}
&red {
color: red
}
&blue {
color: blue
}
}
but a generic way like this
$yellow = yellow;
$red = red;
$blue = blue;
.theme-color-#{$my-color} {
color: #{$my-color};
}
<div class="theme-color-red"></div>
You can use #each:
$colors: red, yellow, blue;
#each $color in $colors {
.theme-color-#{$color} {
color: $color;
}
}
This generates the following CSS:
.theme-color-red {
color: red;
}
.theme-color-yellow {
color: yellow;
}
.theme-color-blue {
color: blue;
}
You can also use #each with a map instead of a list if you want to specify custom color values:
$colors: (red: '#ff0000', yellow: '#fffd62', blue: '#0000ff');
#each $color, $hex in $colors {
.theme-color-#{$color} {
color: $hex;
}
}
Which results in the following CSS:
.theme-color-red {
color: "#ff0000";
}
.theme-color-yellow {
color: "#fffd62";
}
.theme-color-blue {
color: "#0000ff";
}
Related
I have written this #mixin to set styles for light and dark theme in one line.
#mixin setThemeDynamicCSSRule($property, $light-theme-value, $dark-theme-value) {
#{$property}: #{$light-theme-value};
.dark-mode & {
#{$property}: #{$dark-theme-value}
}
}
body {
#include setThemeDynamicCSSRule(color, black, white);
#include setThemeDynamicCSSRule(background-color, white, black);
#include setThemeDynamicCSSRule(font-size, 16px, 32px);
}
This returns me:
body {
color: black;
background-color: white;
font-size: 16px;
}
.dark-mode body {
color: white;
}
.dark-mode body {
background-color: black;
}
.dark-mode body {
font-size: 32px;
}
it keeps repeating .dark-mode body selector for each individual setThemeDynamicCSSRule() call.
It still does the job but ideally I would like css to compile to:
body {
color: black;
background-color: white;
font-size: 16px;
}
.dark-mode body {
color: white;
background-color: black;
font-size: 32px;
}
Not exactly the way your are looking for ... but thinking forward it is the wanted result. And mayby an easier and more neat way to organize your special theme properties in one place.
Wrap your different theme property/values at to a nested map. Than use an adapted mixin.
$themes: (
color: (
'light': 'black',
'dark': 'white',
),
background-color: (
'light': 'white',
'dark': 'black',
),
font-size: (
'light': 16px,
'dark': 32px,
),
);
#mixin setThemeStyles($themes){
#each $property, $values in $themes {
#{$property}: map-get($values, 'light' );
}
.dark-mode & {
#each $property, $values in $themes{
#{$property}: map-get($values, 'dark');
}
}
}
body {
#include setThemeStyles($themes);
}
//######>> RESULT IS YOUR WANTED CSS
body {
color: "black";
background-color: "white";
font-size: 16px;
}
.dark-mode body {
color: "white";
background-color: "black";
font-size: 32px;
}
I am creating a mixin to target a child element.
Example.
Targeting all <a> tags of the parent that has a parent of section---blue
I figure that I can pass the tag as an argument as follows
But I am not getting the desired result
SCSS
#mixin themeParent ($child) {
&--blue $child {
color: getColour("theme", "bluehighlight");
}
&--green $child {
color: getColour("theme", "greenhighlight");
}
&--purple $child {
color: getColour("theme", "purplehighlight");
}
}
.section {
#include themeParent(a);
}
I would have thought that this would compile to
.section--blue a {
color: blue;
}
Can someone please explain to me why?
#mixin themeParent ($child) {
&--blue #{$child} {
color: blue;
}
}
outputs: .section--blue a { color: blue; }
If you want more specificity, just add another &:
#mixin themeParent ($child) {
&#{&}--blue #{$child} {
color: blue;
}
}
outputs: .section.section--blue a { color: blue; }
If you want more scability, just iterate over colors you want:
#mixin themeParent ($child) {
$colors: red, blue, green;
#each $color in $colors {
&#{&}--#{$color} #{$child} {
color: $color;
}
}
}
Put $child in #{$child}.
#mixin themeParent ($child) {
#{$child} {
color: #000;
}
}
.section {
#include themeParent(a)
}
Output:
.section a {
color: #000;
}
If I put this in a simple way, there is no need to pass the tag as a parameter to the mixin function instead, u should pass the color of the element.
<div className="section--blue">
<a>section blue</a>
</div>
<div className="section-green">
<a>section green</a>
</div>
mixin and css
#mixin themeParent ($color) {
color:$color;
}
.section{
&--blue {
a{
#include themeParent(blue);
}
}
--green{
a{
#include themeParent(green);
}
}
}
Hope this is useful.
I am working on theme based localisation. For that I am getting class on body tag for each localisation.
I need to change all variables value based on that class
For more Understanding
$a: #000;
$b= Arial;
if body has class Australia then
$a: #ff0000;
$b: 'Roboto';
Please no js code only by scss
Using #import and !default variables
// ––––––––––––––––––––––––––––––––––––––
// _style.scss
// underscore added to prevent compilation
// ––––––––––––––––––––––––––––––––––––––
$color : red !default;
$font-family: Arial !default;
.foo { color: $color; }
.bar { font-family: $font-family; }
// ––––––––––––––––––––––––––––––––––––––
// style.scss (compile file)
// ––––––––––––––––––––––––––––––––––––––
// redefine variables
$color: blue;
$font-family: Roboto;
// add wrapper if needed (will be added to all selectors)
.australia {
#import '_style.scss';
}
The following example uses a map to define different theme values. The mixin will wrap each selector in a class (the map key) and create global variables to be used inside each selector.
$theme-map:(
'.australia': (color: blue, font-family: Roboto),
'.denmark' : (color: red, font-family: Arial)
);
#mixin theme {
#each $class, $map in $theme-map {
#{$class} & {
$color: map-get($map, color) !global;
$font-family: map-get($map, font-family) !global;
#content;
}
}
}
.foo {
#include theme {
color: $color;
font-family: $font-family;
}
}
.bar{
#include theme {
background-color: $color;
}
}
Output:
.australia .foo {
color: blue;
font-family: Roboto;
}
.denmark .foo {
color: red;
font-family: Arial;
}
.australia .bar {
background-color: blue;
}
.denmark .bar {
background-color: red;
}
PS. in the near future CSS variables will ease this type of work using variable inheritance.
.australia {
--color: red;
--font-family : Arial;
}
.denmark {
--color: blue;
--font-family : Roboto;
}
.foo {
color: var(--color);
font-family: var(--font-family);
}
.bar {
backgound-color: var(--color);
}
I have this
$colors:
"dark" #3E3E3E,
"darker" #3E3E3E,
"light" #ECECF0,
"green" #00A87B,
"yellow" #FFBB3B,
"red" #FF4633,
"white" #FFFFFF,
"black" #000000,
"blue" #436FB6
;
#each $color in $colors{
// .btn-color
.btn-#{nth($color, 1)}{
background: nth($color, 2);
color: #fff;
}
// .color / color
.#{nth($color, 1)}, #{nth($color, 1)}{
color: nth($color, 2) !important;
a{
color: nth($color, 2);
}
}
// .color-bg
.#{nth($color, 1)}-bg {
background: nth($color, 2);
}
}
It dynamically creates various classes. How can I extend this to make variables for each $colors example — i need to use $dark to reach the dark value from $colors
If you are going to automate color variations I recommend you to take a look into the native color functions provided by Sass (http://sass-lang.com/documentation/Sass/Script/Functions.html).
Here is an example based on a color map (IMO simpler to work with compared to list):
$colors:(
green : #00A87B,
yellow : #FFBB3B,
red : #FF4633,
blue : #436FB6,
white : #FFFFFF,
black : #000000
);
#each $name, $color in $colors {
.color {
&-#{$name}{
background-color: $color;
// create variations (if not black or white)
#if $color != white and $color != black {
&.extra-light { background-color: mix($color, white, 25%); }
&.light { background-color: mix($color, white, 50%); }
&.semi-light { background-color: mix($color, white, 75%); }
&.extra-dark { background-color: mix($color, black, 25%); }
&.dark { background-color: mix($color, black, 50%); }
&.semi-dark { background-color: mix($color, black, 75%); }
}
}
}
}
CSS output
.color-green { background-color: #00A87B;}
.color-green.extra-light { background-color: #bfe9de;}
.color-green.light { background-color: #80d4bd;}
.color-green.semi-light { background-color: #40be9c;}
.color-green.extra-dark { background-color: #002a1f;}
.color-green.dark { background-color: #00543e;}
.color-green.semi-dark { background-color: #007e5c;}
.color-yellow { background-color: #FFBB3B;}
.color-yellow.extra-light { background-color: #ffeece;}
.color-yellow.light { background-color: #ffdd9d;}
.color-yellow.semi-light { background-color: #ffcc6c;}
.color-yellow.extra-dark { background-color: #402f0f;}
.color-yellow.dark { background-color: #805e1e;}
.color-yellow.semi-dark { background-color: #bf8c2c;}
.color-red { background-color: #FF4633;}
.color-red.extra-light { background-color: #ffd1cc;}
.color-red.light { background-color: #ffa399;}
.color-red.semi-light { background-color: #ff7466;}
.color-red.extra-dark { background-color: #40120d;}
.color-red.dark { background-color: #80231a;}
.color-red.semi-dark { background-color: #bf3526;}
.color-blue { background-color: #436FB6;}
.color-blue.extra-light { background-color: #d0dbed;}
.color-blue.light { background-color: #a1b7db;}
.color-blue.semi-light { background-color: #7293c8;}
.color-blue.extra-dark { background-color: #111c2e;}
.color-blue.dark { background-color: #22385b;}
.color-blue.semi-dark { background-color: #325389;}
.color-white { background-color: #FFFFFF;}
.color-black { background-color: #000000;}
Function based approach:
$colors:(
green : #00A87B,
yellow : #FFBB3B,
red : #FF4633,
blue : #436FB6,
white : #FFFFFF,
black : #000000
);
#function get-color($color, $variant: null){
$color: map-get($colors, $color);
#return map-get((
extra-light: mix($color, white, 25%),
light: mix($color, white, 50%),
semi-light: mix($color, white, 75%),
semi-dark: mix($color, black, 75%),
dark: mix($color, black, 50%),
extra-dark: mix($color, black, 25%)
),$variant) or $color;
}
.class { color: get-color(green); }
.class { color: get-color(green, semi-light); }
.class { color: get-color(yellow, dark); }
Ideally I want to create a mixin to style all the placeholder pseudo classes. I'm not sure if this is even possible. Here's what I have:
#mixin placeholder($color) {
::-webkit-input-placeholder{
color: $color;
}
:-moz-placeholder {
color: $color;
}
::-moz-placeholder {
color: $color;
}
:-ms-input-placeholder {
color: $color;
}
}
Which ideally would be used like this:
input {
&#placeholder(red);
}
And would result in this CSS:
input::-webkit-input-placeholder{
color: red;
}
input:-moz-placeholder {
color: red;
}