3
votes

I was able to find many different approaches on how to make a switchable themes in SASS I wasn't able to figure out how can I apply that approach to bootstrap overrides. Let's say I want to have light and dark theme and both themes would override bootstraps colors differently.

// Light-theme
$theme-colors: (
    "primary": #8A2F4F
);

// Dark-theme
$theme-colors: (
    "primary": #fff
);

In the example above are overrides for primary of theme-colors. How can I conditionally set them based on theme the user has selected?

2
There are many ways, you can have different CSS files, or switch using CSS variables, or add different class to html. - Prajwal
Well then show me some that I can use to conditionally override bootstrap's variables. F. e. this codeburst.io/a-successful-sass-theme-structure-ca9d1c477dc7 is not applicable because I need to conditionally override bootstrap's variables and not use the mixin described in article. - Maroš Beťko
This is very broad. Are you asking how to switch between different custom CSS themes that were generated via custom SASS, or are you simply asking how to generate different custom CSS themes via SASS? - Zim

2 Answers

0
votes

Well,

there are many ways to do this. I'd suggest you to generate multiple CSS files based on the _variables.scss file. All you have to do is build new theme with different variable file. You can check this method in my public repo.

Other way would be to use CSS custom variables (called as custom properties). You can do something like this. I've just copy pasted and altered the CSS. It is just to give an idea.

in sass file,

$theme-colors: (
    "primary": var(--primary-color);
);

and in other variable file,

element.dark {
  --primary-color: black;
} 
element.light {
  --primary-color: white;
} 

These are two method I would suggest.

-1
votes

Here is how I did it with React, Bootstrap and SASS:

In an index.scss file:

div#blue {
  @import './blue.scss';
}

div#red {
  @import './red.scss';
}

// The rest of bootstrap
// Seems to be necessary to import twice to get fonts to work
@import "node_modules/bootstrap/scss/bootstrap";

Then red.scss I over-ride Boostrap where needed:

$theme-colors: (
        "primary": red,
);

// The rest of bootstrap
@import "node_modules/bootstrap/scss/bootstrap";

blue.scss is similar.

Finally my top level React component:

import './index.css'
import * as React from 'react'
import Button from 'react-bootstrap/Button'

export const Container = () => {

const [color, setColor] = useState('red');

const buttonClick = () => {
    if (color === 'red') setColor('blue')
    if (color === 'blue') setColor('red')
}

return (
        <div id={theme} >
            Switch themes...
            <Button variant="primary" onClick={buttonClick}>Button</Button>
        </div>
    )
}

Press the button and it will change from red to blue. I am guessing that a className rather than a div selector is a better way to do this - but this approach is working for me so I am happy. Not sure how robust this solution is in complex applications yet.