I want to add a different theme when i add "dark-theme" class to body. My implementation looks like this:
#import '../../../../node_modules/angular-grids/styles/material.scss';
.app-dark {
#import '../../../../node_modules/angular-grids/styles/material-dark.scss';
}
Without any luck. Any clue on how to do this?
There are two methods in order to do that. Both of them include mixins.
meta.load-css
The sass:meta feature gives the ability to do what you want.
Say you have this scss file with a theme:
//theme/_code.scss
$border-contrast: false !default;
code {
background-color: #6b717f;
color: #d2e1dd;
#if $border-contrast {
border-color: #dadbdf;
}
}
you can include that code inside another scss file like so:
// other-theme.scss
#use "sass:meta";
body.dark {
#include meta.load-css("theme/code",
$with: ("border-contrast": true));
}
This will result in the following css:
body.dark code {
background-color: #6b717f;
color: #d2e1dd;
border-color: #dadbdf;
}
You can read more about this feature here
old fashioned mixin
But you can do basically the same thing if you use mixin and include.
So, let's say you have this class you want to import into another class:
.title {
font-size: 2em;
font-weight: bold;
}
And another sass file with another theme:
.dark-theme {
.title {
font-size: 2em;
font-weight: bold;
color: white;
}
}
You can use a scss mixin and import it into both files:
mixin.scss
#mixin shared-items() {
.title {
font-size: 2em;
font-weight: bold;
}
}
then, in the theme files:
white-theme.scss
#import './mixin.scss';
/* will be included as is without a parent class */
#include shared-items;
dark-theme.scss
#import './mixin.scss';
/* will be included inside the dark-theme class */
.dark-theme {
.title {
color: white;
}
#include shared-items;
}
this will generate this css:
.title {
font-size: 2em;
font-weight: bold;
}
.dark-theme {
.title { color: white; }
.title {
font-size: 2em;
font-weight: bold;
}
}
Notice that you can also pass parameters to mixin and use them as functions.
So you can easily pass colors and use them with your theme variables.
for example:
# an example of giving a color to a placeholder mixin:
#mixin nk-placeholder($color: #C4C4CC) {
&::-webkit-input-placeholder {
color: $color;
font: inherit;
}
&::-moz-placeholder {
color: $color;
font: inherit;
}
&:-ms-input-placeholder {
color: $color;
font: inherit;
}
&:-moz-placeholder {
color: $color;
font: inherit;
}
&::placeholder {
color: $color;
font: inherit;
}
}
# same thing as above
#mixin shared-items($text-color: black) {
.title {
font-size: 2em;
font-weight: bold;
color: $text-color;
}
}
.white-theme {
#include shared-items;
}
.dark-theme {
#include shared-items(white);
}
Related
I'm trying to use a mixin to make the code less repetitive, but I can't reach the nested elements.
Could anyone tell me if this approach is possible?
#mixin schema-calendar($backgroundColor: var(--ion-color-primary), $titleColor: var(--ion-color-secondary)) {
background-color: $backgroundColor !important;
.switch-btn,
ion-icon {
color: $titleColor !important;
text-transform: uppercase;
}
.week-toolbar li {
color: $titleColor !important;
font-weight: 900;
}
button.today p { color: $titleColor !important; }
button.on-selected {
p { color: var(--ion-color-secondary-contrast) !important;}
}
}
ion-calendar.schemaDefault {
#include schema-calendar();
}
ion-calendar.schemaBlackRed {
#include schema-calendar(var(--ion-card-black-red));
}
ion-calendar.schemaIndigo {
#include schema-calendar(var(--ion-card-indigo), var(--ion-color-light));
}
When used directly in css it works perfectly, I know that when scss is compiled to css the code is modified but the result is the same, but when I use the mixin according to the code above, only the background-color property is applied.
ion-calendar.schemaBlackRed {
// primaryColor: 'var(--ion-card-blackred)', secondaryColor: 'var(--ion-color-secondary)', titleColor: 'var(--ion-color-secondary)',
background-color: var(--ion-card-black-red) !important;
.switch-btn,
ion-icon {
color: var(--ion-color-secondary) !important;
text-transform: uppercase;
}
.week-toolbar li {
color: var(--ion-color-secondary) !important;
font-weight: 900;
}
button.today p { color: var(--ion-color-secondary) !important; }
button.on-selected {
p { color: var(--ion-color-secondary-contrast) !important;}
}
}
I found that the problem was occurring because I had included the style at the page level, moved the code from the initial Ionic load and everything worked as expected.
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);
}
Here's the sample:
.my-class {
font-size: 12px;
}
.my-another-class {
/* here I want to include .my-class style */
.my-class;
border: 0;
}
Can I include one css class into another or not?
You can define multiple targets for the .my-class rule, then specify further rules just for .my-another-class:
.my-class,
.my-another-class {
font-size: 12px;
}
.my-another-class {
border: 0;
}
You can even then override certain properties, for example
.my-class,
.my-another-class {
color: red;
font-size: 12px;
}
.my-another-class {
border: 0;
color: blue; /* overrides color: red; on .my-another-class */
}
You can't use a construction like this in plain CSS.
Preprocessors such as Less and Sass support this behaviour with mixins.
You can't, but you can do something like this:
.my-class, .my-another-class{
font-size: 12px;
}
.my-another-class {
border: 0;
}
In SCSS, properties with common prefix can be described as nested properties. Thus, as in the example,
.funky{
font: 2px/3px{
family: fantasy;
size: 30em;
weight: bold;
}
}
is compiled to:
.funky{
font: 2px/3px;
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
How do I do a similar thing with properties with common affix? How can I write a nested property that would be compiled to this:
.funky{
color: red;
background-color: green;
border-color: blue;
}
Sass has no construct for such a concept. You'll have to patch it or write a verbose mixin to do it.
#mixin color($background: null, $border: null, $font: null) {
background-color: $background;
border-color: $border;
color: $font;
}
.foo {
#include color($background: green, $font: red);
}
Some body know how can i use nested mixins or functions in SASS?
I have something like this:
#mixin A(){
do something....
}
#mixin B($argu){
#include A();
}
yeah you already doing it right. You can call first mixin in second one. check this pen http://codepen.io/crazyrohila/pen/mvqHo
You can multi nest mixins, you can also use place holders inside mixins..
#mixin a {
color: red;
}
#mixin b {
#include a();
padding: white;
font-size: 10px;
}
#mixin c{
#include b;
padding:5;
}
div {
#include c();
}
which gives out CSS
div {
color: red;
padding: white;
font-size: 10px;
padding: 5;
}
As mentioned in the other answers, you can include mixins in other mixins. In addition, you can scope your mixins.
Example
.menu {
user-select: none;
.theme-dark & {
color: #fff;
background-color: #333;
// Scoped mixin
// Can only be seen in current block and descendants,
// i.e., referencing it from outside current block
// will result in an error.
#mixin __item() {
height: 48px;
}
&__item {
#include __item();
&_type_inverted {
#include __item();
color: #333;
background-color: #fff;
}
}
}
}
Will output:
.menu {
user-select: none;
}
.theme-dark .menu {
color: #fff;
background-color: #333;
}
.theme-dark .menu__item {
height: 48px;
}
.theme-dark .menu__item_type_inverted {
height: 48px;
color: #333;
background-color: #fff;
}
Scoping mixins means that you can have multiple mixins named the same in different scopes without conflicts arising.