最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - CSS variables in Material ui - createMuiTheme - Stack Overflow

programmeradmin2浏览0评论

I am trying to create a material ui theme using the existing colors defined as css variables my-pallette.scss:

:root {
  --primary-color: '#FF0000';
  ...
}

And use this like this:

import { createMuiTheme } from '@material-ui/core/styles';

export const muiTheme = createMuiTheme({
  palette: {
    primary: {
      main: 'var(--primary-color)',
    },
  },
});

This throws an error:

Uncaught Error: Material-UI: Unsupported var(--primary-color) color. We support the following formats: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla().

According to this Github thread: Support CSS variables as theme option this is unsupported at the moment.

Is there any workaround so I can use var(--primary-color) as a primary color in material ui createMuiTheme?

The end goal is to use material ui components in their simplest form with their primary, scondary, etc colors overwritten by my colors.

<Radio color="primary" />

I have tried using the colors from my pallets like this:

const cssVariables = {
  primaryColor: getComputedStyle(document.documentElement).getPropertyValue('var(--primary-color)'),
};

and use cssVariables.primaryColor but this doesn't work and feels very counterintuitive.

My last solution is to duplicate the palette as a normal object as use it as it is but this seems a nightmare for maintenance.

I am trying to create a material ui theme using the existing colors defined as css variables my-pallette.scss:

:root {
  --primary-color: '#FF0000';
  ...
}

And use this like this:

import { createMuiTheme } from '@material-ui/core/styles';

export const muiTheme = createMuiTheme({
  palette: {
    primary: {
      main: 'var(--primary-color)',
    },
  },
});

This throws an error:

Uncaught Error: Material-UI: Unsupported var(--primary-color) color. We support the following formats: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla().

According to this Github thread: Support CSS variables as theme option this is unsupported at the moment.

Is there any workaround so I can use var(--primary-color) as a primary color in material ui createMuiTheme?

The end goal is to use material ui components in their simplest form with their primary, scondary, etc colors overwritten by my colors.

<Radio color="primary" />

I have tried using the colors from my pallets like this:

const cssVariables = {
  primaryColor: getComputedStyle(document.documentElement).getPropertyValue('var(--primary-color)'),
};

and use cssVariables.primaryColor but this doesn't work and feels very counterintuitive.

My last solution is to duplicate the palette as a normal object as use it as it is but this seems a nightmare for maintenance.

Share Improve this question asked Sep 16, 2020 at 8:40 Cezar CobuzCezar Cobuz 1,2072 gold badges17 silver badges35 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 8

The MUI team is currently working on a solution to support CSS variables. You can track the progress here and check the details here. There is also an official documentation here.

UPD of 21.12.2022

CSS variables are supported now by the MUI as an experimental API, check documentation here.

The workaround posted by NearHuscarl gets the job done, but there's a flicker caused by the palette change. This can be avoided with lazy initialization in useState.

const cssVar = (name: string) =>
  getComputedStyle(document.documentElement).getPropertyValue(name).trim();

const App: React.FC = () => {
  const [theme] = useState(() =>
    createTheme({
      palette: {
        primary: {
          main: cssVar("--color-primary"),
          light: cssVar("--color-primary-light"),
          dark: cssVar("--color-primary-dark"),
          bg: cssVar("--color-primary-bg"),
          contrastText: cssVar("--color-primary-contrast-text"),
        },
      },
    })
  );

  return (
    <ThemeProvider theme={theme}>
      <YourApp />
    </ThemeProvider>
  );
};

The ugly workaround works, but I suspect you are calling getComputedStyle() in the module scope when the stylesheets may not be initialized yet.

Try putting it in the render method like this.

const [theme, setTheme] = React.useState(null);

React.useLayoutEffect(() => {
  const color = getComputedStyle(document.documentElement)
    .getPropertyValue("--your-css-color")
    .trim(); // the result have a leading whitespace.

  setTheme(
    createMuiTheme({
      palette: {
        primary: {
          main: color
        }
      }
    })
  );
}, []);

Live Demo

Setting colors from theme options may be more effectively. With this method you could define material ui colors as css variables.

import React, { useEffect } from 'react'
import { createTheme, ThemeProvider } from '@mui/material/styles'

import { indigo, amber } from '@mui/material/colors'
const themeOptions = createTheme({
  palette: {
    primary: { main: indigo[500] },
    secondary: { main: amber[600] },
    background: { default: '#F3F6F9' },
  },
})
const colorKeys = ['background', 'common', 'error', 'grey', 'info', 'primary', 'secondary', 'success', 'text', 'warning']
const r = document.querySelector(':root')
const AppThemeProvider = ({ children }) => {
  useEffect(() => {
    colorKeys.forEach((color) => {
      const themeColorObj = themeOptions.palette[color]
      for (const key in themeColorObj) {
        if (Object.hasOwnProperty.call(themeColorObj, key)) {
          const colorVal = themeColorObj[key]
          r.style.setProperty(`--color-${color}-${key}`, colorVal)
        }
      }
    })
  }, [])
  return <ThemeProvider theme={themeOptions}>{children}</ThemeProvider>
}
export default AppThemeProvider

With this way you could use css variables as sass or common css.

.dx-link-edit {
  color: var(--color-primary-main);}
发布评论

评论列表(0)

  1. 暂无评论