JSS 中的 MUI Global Class 名称有多可靠?
How reliable are MUI Global Class names in JSS?
我有这样的代码:
const formControlStyles = {
root: {
'&:hover .MuiFormLabel-root': {
}
}
}
在主题覆盖中使用 class 名称访问其他组件是否安全?此外,是否有 JSS 方式从其他组件嵌套样式?
更新 v5
这个答案最初是关于 Material-UI 的 v4 写的。在 v5 中,Material-UI 不再使用全局 class 名称来应用默认样式 -- 用于默认样式的 classes 具有 class 由 Emotion 生成的名称。全局 class 名称仍然适用,但它们不再受嵌套主题的影响,因此在 v5 中,利用全局 class 名称进行覆盖是完全安全的,而无需使用 [class*=...
下面我的原始答案中提到的语法。
使用全局 class 名称是相当安全的,但有一个警告(在 v4 中)。如果您利用嵌套主题,嵌套主题中应用的全局 class 名称将具有不可预测的后缀(例如 MuiFormLabel-root-371
)。这个后缀是必要的,因为与嵌套主题关联的默认样式可以不同。
为了以完全安全的方式定位 class 名称,您可以使用 *=
attribute selector (e.g. [class*="MuiFormLabel-root"]
) which checks to see if the element has a class name that contains MuiFormLabel-root
rather than needing to match it exactly. You can see this approach used within Material-UI itself here.
只要您不打算使用嵌套主题,使用精确匹配全局 class 名称的更简单语法是安全的(并且可读性更高)。另一种方法是在嵌套组件上指定 JSS class,并使用 referring to another rule in the same stylesheet 的 JSS 语法引用 class(例如,在我的示例中为 $myFormLabel
),但这需要能够将 class(例如我的示例中的 classes.myFormLabel
)应用于嵌套组件。
下面的示例演示了使用嵌套主题时出现的问题(以及一些可能的解决方案)。
import React from "react";
import {
ThemeProvider,
createMuiTheme,
makeStyles
} from "@material-ui/core/styles";
import FormLabel from "@material-ui/core/FormLabel";
const theme1 = createMuiTheme();
const theme2 = createMuiTheme({
overrides: {
MuiFormLabel: {
root: {
color: "#00ff00"
}
}
}
});
const useStyles = makeStyles({
mostlySafe: {
"&:hover .MuiFormLabel-root": {
color: "red"
}
},
safeButTediousAndMoreErrorProneSyntax: {
'&:hover [class*="MuiFormLabel-root"]': {
color: "purple"
}
},
alternativeApproach: {
"&:hover $myFormLabel": {
color: "blue"
}
},
myFormLabel: {}
});
export default function App() {
const classes = useStyles();
return (
<ThemeProvider theme={theme1}>
<div>
<div className={classes.mostlySafe}>
<FormLabel>FormLabel within top-level theme</FormLabel>
</div>
<ThemeProvider theme={theme2}>
<div className={classes.mostlySafe}>
<FormLabel>
FormLabel within nested theme (hover styling doesn't work)
</FormLabel>
</div>
<div className={classes.safeButTediousAndMoreErrorProneSyntax}>
<FormLabel>
FormLabel within nested theme using safe approach
</FormLabel>
</div>
<div className={classes.alternativeApproach}>
<FormLabel className={classes.myFormLabel}>
FormLabel within nested theme without using global class names
</FormLabel>
</div>
</ThemeProvider>
</div>
</ThemeProvider>
);
}
我有这样的代码:
const formControlStyles = {
root: {
'&:hover .MuiFormLabel-root': {
}
}
}
在主题覆盖中使用 class 名称访问其他组件是否安全?此外,是否有 JSS 方式从其他组件嵌套样式?
更新 v5
这个答案最初是关于 Material-UI 的 v4 写的。在 v5 中,Material-UI 不再使用全局 class 名称来应用默认样式 -- 用于默认样式的 classes 具有 class 由 Emotion 生成的名称。全局 class 名称仍然适用,但它们不再受嵌套主题的影响,因此在 v5 中,利用全局 class 名称进行覆盖是完全安全的,而无需使用 [class*=...
下面我的原始答案中提到的语法。
使用全局 class 名称是相当安全的,但有一个警告(在 v4 中)。如果您利用嵌套主题,嵌套主题中应用的全局 class 名称将具有不可预测的后缀(例如 MuiFormLabel-root-371
)。这个后缀是必要的,因为与嵌套主题关联的默认样式可以不同。
为了以完全安全的方式定位 class 名称,您可以使用 *=
attribute selector (e.g. [class*="MuiFormLabel-root"]
) which checks to see if the element has a class name that contains MuiFormLabel-root
rather than needing to match it exactly. You can see this approach used within Material-UI itself here.
只要您不打算使用嵌套主题,使用精确匹配全局 class 名称的更简单语法是安全的(并且可读性更高)。另一种方法是在嵌套组件上指定 JSS class,并使用 referring to another rule in the same stylesheet 的 JSS 语法引用 class(例如,在我的示例中为 $myFormLabel
),但这需要能够将 class(例如我的示例中的 classes.myFormLabel
)应用于嵌套组件。
下面的示例演示了使用嵌套主题时出现的问题(以及一些可能的解决方案)。
import React from "react";
import {
ThemeProvider,
createMuiTheme,
makeStyles
} from "@material-ui/core/styles";
import FormLabel from "@material-ui/core/FormLabel";
const theme1 = createMuiTheme();
const theme2 = createMuiTheme({
overrides: {
MuiFormLabel: {
root: {
color: "#00ff00"
}
}
}
});
const useStyles = makeStyles({
mostlySafe: {
"&:hover .MuiFormLabel-root": {
color: "red"
}
},
safeButTediousAndMoreErrorProneSyntax: {
'&:hover [class*="MuiFormLabel-root"]': {
color: "purple"
}
},
alternativeApproach: {
"&:hover $myFormLabel": {
color: "blue"
}
},
myFormLabel: {}
});
export default function App() {
const classes = useStyles();
return (
<ThemeProvider theme={theme1}>
<div>
<div className={classes.mostlySafe}>
<FormLabel>FormLabel within top-level theme</FormLabel>
</div>
<ThemeProvider theme={theme2}>
<div className={classes.mostlySafe}>
<FormLabel>
FormLabel within nested theme (hover styling doesn't work)
</FormLabel>
</div>
<div className={classes.safeButTediousAndMoreErrorProneSyntax}>
<FormLabel>
FormLabel within nested theme using safe approach
</FormLabel>
</div>
<div className={classes.alternativeApproach}>
<FormLabel className={classes.myFormLabel}>
FormLabel within nested theme without using global class names
</FormLabel>
</div>
</ThemeProvider>
</div>
</ThemeProvider>
);
}