Dynamic theming in SCSS

Viewed 329

So say I have two maps in SCSS,

$dark-theme: (
    primary: #BB86FC,
    primary-varient: #3700B3,
    secondary: #03DAC6,
    background: #2c2e43,
    error: #CF6679,
);

$light-theme: (
    primary: #6200EE,
    primary-varient: #3700B3,
    secondary: #03DAC6,
    secondary-varient: #018786,
    background: #FFFFFF,
    error: #B00020,
);

If I were to set a background colour based on the background value of the map, how could I switch between the two theme maps using a switch on the webpage? So when I switch between them the background colour changes to be the value from the other map.

1 Answers

You can set the theme class name to the root and change it with js. I would recommend having all themes in a map, instead of separatelly. Like:

$themes: (
  dark-theme: (
    primary: #BB86FC,
    ...
  ),
  light-theme: (
    primary: #6200EE,
    ...
  )
);

And then iterate through them:

@each $theme in $themes {
  body.#{$theme} .example-class{
    color: map-get($theme, property);
  }
}

Now, you have to change the body class to change the theme:

const 
[button] = document.getElementsByTagName('button'),
[body] = document.getElementsByTagName('body')

button.addEventListener('click', () => {
  body.classList.add('light-theme')
})

Let me add a very simple example:

const [ body ] = document.getElementsByTagName('body'),
 [button] = document.getElementsByTagName('button')
 
 button.addEventListener('click', () => body.classList.toggle('dark'))
body button {
  background: #fff;
  color: #000;
}

body.dark button {
  background: #000;
  color: #fff;
}
<body>
  <button>Change color</button>
</body>

Related