基于变体为MUI组件应用嵌入式嵌套样式失效问题求助
我明白你现在遇到的困扰——想用更简洁的嵌套方式给MUI Button的变体+颜色组合写样式,但&.primary这种写法始终不生效对吧?这其实是因为MUI的类名生成规则和你预想的不一样,咱们一步步来拆解问题、解决它:
为什么你的嵌套写法不生效?
当你给Button设置variant="contained"和color="primary"时,MUI不会给按钮同时添加contained和primary两个独立类名,而是生成一个组合类名,比如MuiButton-containedPrimary。你写的&.primary找不到对应的DOM类,自然样式不会生效。
解决方案1:针对MUI组合类名编写样式
调整makeStyles的写法,直接用MUI生成的完整组合类名作为嵌套选择器,这样就能精准匹配对应的按钮状态,同时保持代码的简洁性:
const useStyles = makeStyles({ contained: { backgroundColor: 'var(--mdh-button-background-color)', fontFamily: 'var(--mdh-button-font-family)', // 匹配contained + primary的组合类 '&.MuiButton-containedPrimary': { color: 'var(--mdh-button-secondary-background-color)', }, // 匹配contained + secondary的组合类 '&.MuiButton-containedSecondary': { color: 'var(--mdh-button-secondary-background-color)' }, '&:hover': { backgroundColor: 'var(--mdh-button-hover-background-color)', color: 'var(--mdh-button-hover-text-color)' }, '&:focus': { backgroundColor: 'var(--mdh-button-focus-background-color)', color: 'var(--mdh-button-focus-text-color)' }, // 匹配禁用状态的全局类 '&.Mui-disabled': { backgroundColor: 'var(--mdh-button-disabled-background-color)' } }, outlined: { // 简化边框颜色写法,不用分开写四个方向 borderColor: 'var(--mdh-button-background-color)', '&.MuiButton-outlinedPrimary': { color: 'var(--mdh-button-background-color)' }, '&.MuiButton-outlinedSecondary': { color: 'var(--mdh-button-secondary-background-color)' }, '&:hover': { borderColor: 'var(--mdh-button-hover-background-color)' }, '&:focus': { borderColor: 'var(--mdh-button-focus-background-color)' } }, text: { '&.MuiButton-textPrimary': { color: 'var(--mdh-button-background-color)', '&:hover, &:focus': { color: 'var(--mdh-button-disabled-background-color)' } }, '&.MuiButton-textSecondary': { color: 'var(--mdh-button-secondary-background-color)', '&:hover, &:focus': { color: 'var(--mdh-button-disabled-background-color)' } } } })
然后在Storybook中,只需要传递基础变体类即可,不用再单独处理outlinedPrimary这类组合类:
const Template: Story<ButtonProps> = (args: any) => { const classes = useStyles() args.classes = { contained: classes.contained, outlined: classes.outlined, text: classes.text } return <Button {...args}>Button</Button> }
解决方案2:用MUI主题全局定制(更适合设计系统)
既然你在开发基于MUI的设计系统,更推荐用createTheme全局定制组件样式,这样不需要每个组件都手动传递classes,所有Button都会自动应用统一样式,维护成本更低:
import { createTheme, ThemeProvider } from '@material-ui/core/styles'; import MaterialButton from '@material-ui/core/Button' import './button-design-tokens.module.css' // 全局定制MUI主题 const theme = createTheme({ components: { MuiButton: { styleOverrides: { contained: { backgroundColor: 'var(--mdh-button-background-color)', fontFamily: 'var(--mdh-button-font-family)', '&.MuiButton-containedPrimary': { color: 'var(--mdh-button-secondary-background-color)', }, '&.MuiButton-containedSecondary': { color: 'var(--mdh-button-secondary-background-color)' }, '&:hover': { backgroundColor: 'var(--mdh-button-hover-background-color)', color: 'var(--mdh-button-hover-text-color)' }, '&:focus': { backgroundColor: 'var(--mdh-button-focus-background-color)', color: 'var(--mdh-button-focus-text-color)' }, '&.Mui-disabled': { backgroundColor: 'var(--mdh-button-disabled-background-color)' } }, outlined: { borderColor: 'var(--mdh-button-background-color)', '&.MuiButton-outlinedPrimary': { color: 'var(--mdh-button-background-color)' }, '&.MuiButton-outlinedSecondary': { color: 'var(--mdh-button-secondary-background-color)' }, '&:hover': { borderColor: 'var(--mdh-button-hover-background-color)' }, '&:focus': { borderColor: 'var(--mdh-button-focus-background-color)' } }, text: { '&.MuiButton-textPrimary': { color: 'var(--mdh-button-background-color)', '&:hover, &:focus': { color: 'var(--mdh-button-disabled-background-color)' } }, '&.MuiButton-textSecondary': { color: 'var(--mdh-button-secondary-background-color)', '&:hover, &:focus': { color: 'var(--mdh-button-disabled-background-color)' } } } } } } }); export const Button: React.FC<ButtonProps> = (props: ButtonProps) => { return ( <ThemeProvider theme={theme}> <MaterialButton {...props}>{props.children}</MaterialButton> </ThemeProvider> ) }
这种方式下,你不需要在Storybook里手动处理classes,所有Button都会自动继承主题中的样式,非常适合设计系统的统一维护。
内容的提问来源于stack exchange,提问作者thebugsdontwork
相关产品推荐
相关产品推荐

