Material UI: Change theme color by SASS variables
Asked Answered
B

6

9

I know we can edit the theme of material UI but I was thinking on making it dynamic, where in we can have SASS Variables set, and it will automatically update the Material UI theme.

I use sass to design my page, and here's the sample of variables I use:

$primary-color: #1E79C7;
$secondary-color: #E5681A;

Currrently for me I do the following for the material ui button, because i want my design to be on one place as much as possible

.app-button-blue {
  background-color: $primary-color !important; 
  margin: 5px;
}

.app-button-gray {
  background: transparent !important;
  box-shadow: none !important;
}

.app-button-white {
  background: transparent !important;
  box-shadow: none !important;
  border: $primary-color solid 1px !important;
}

Is there a way for me to use this SASS variables on overwriting the theme of material ui - like setting the primary and secondary colors?

Bradstreet answered 30/9, 2018 at 7:56 Comment(3)
Could you clarify what you mean by making the theme dynamic.Beavers
@LukePeavey, I updated my question. Hope it can help you understand my question! Thanks :)Bradstreet
cool, ill take another lookBeavers
W
10

It is possible to populate the MaterialUI theme from Sass/Scss variables using Webpack wizadry

palette.scss

$primary: #1E79C7;
$secondary: #E5681A;

:export {
  primary: $primary;
  secondary: $secondary;
}

theme.js

import { createMuiTheme } from '@material-ui/core/styles'
import palette from './palette.scss'

export const theme = createMuiTheme({
  palette: {
    primary: {
      main: palette.primary,
    },
    secondary: {
      main: palette.secondary,
    },
  }
})

App.js

import React from 'react'
import { ThemeProvider } from '@material-ui/core/styles'
import { theme } from './theme'

export const App = () => {
  return (
    <ThemeProvider theme={theme}>
       // App
    </ThemeProvider>
  )
}

This means you can use Sass to style and color both your non Material UI and Material UI components from one source of truth

To style other components, just use Sass imports

@import './palette.scss'

.app-button-blue {
  background-color: $primary; // removed !important cos there's usually a better way
  margin: 5px;
}
Wigwag answered 12/3, 2021 at 15:45 Comment(0)
B
6

Material UI uses a javascript based style solution (JSS) instead of a CSS pre-processor like SCSS (see style solution).

This means its not possible to customize the Material UI theme via SCSS variables. Nor is it possible to access the theme in your CSS/SCSS styles.

If you want to use SCSS for styling/theming, you might consider Material Web Components instead.

Beavers answered 2/10, 2018 at 22:44 Comment(4)
can Material Web Components be used in Reactjs?Holiday
@SamYC ReactJs doesn't care how you will pass styles to components. You can use css, scss, jss or other techs to provide styling to html made by reactjsOutland
Material-UI uses JS based styles but those can be easily manipulated too. material-ui.com/customization/components check code samples there. There is makeStyles for it. Inside makeStyles code is similar to scss. Can even use '&:hover' and similar.Outland
Material UI no longer uses JSSBluebonnet
W
3

An example on this GitHub issue suggests how you can do this.

import React from 'react';
import { withStyles } from '@material-ui/core';

const cssVariables = (theme) => ({
  '@global': {
    ':root': {
      '--color-primary': theme.palette.primary.main,
      '--color-secondary': theme.palette.secondary.main,
    }
  }
});

const RootComponent = () => {
  return <div>Whatever...</div>
}

export default withStyles(cssVariables, RootComponent);

Having in mind RootComponent initialises inside ThemeProvider.

Wellestablished answered 4/9, 2020 at 9:58 Comment(1)
This works as <GlobalStyles styles={{":root": { ... }}} />Predicament
M
1

There's a way to define the theme variables in the JS-side and use them in the CSS-side to keep a single source of truth and allow dynamic theme switching. You can check the solution I posted on the MUI GitHub repository.

Mundane answered 27/12, 2021 at 21:26 Comment(0)
M
0

It may not be exactly what you wanted to achieve, but the following article explains how you can export SASS variables. https://til.hashrocket.com/posts/sxbrscjuqu-share-scss-variables-with-javascript Afterwards you can import these in JS and use them to set up your theme.

Marcmarcano answered 29/8, 2019 at 10:39 Comment(0)
A
0

Initialize your variables in the <body> tag styles.

body {
  --my-var: #fff;
}

Then it will be visible for Material UI Drawers and other components, that opening with portals.

UPD 2:

There is another way to do the thing above dynamically. So, if you want to use CSS Variables to change Material UI components styles, for example - for Drawer (that uses React-Portals to lift up a component to top level of the DOM). The problem was that by MUI lifted up components were out of the 'root' div and CSS Variables could not reach these components.

Solution:

  const [theme, setTheme] = useState('light');

  useEffect(() => {
    document.body.classList.remove('dark', 'light');
    document.body.classList.add(theme);
  }, [theme]);

and add variables to these classNames in some file.

File theme.scss:

.light {
  --theme-color: #A80000;
  --theme-page-background: #FFF;
  $theme-page-background: #FFF;
  --theme-page-text: $color-text;
}

.dark {
  --theme-color: #0000A8;
  --theme-page-background: #111;
  $theme-page-background: #111;
  --theme-page-text: #FFF;
}

Import your theme.scss file to the project and it have to work.

Americanism answered 27/10, 2022 at 22:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.