Material-UI中TableRow组件selected样式无法覆盖的问题求助
解决Material-UI TableRow选中样式优先级问题(无需!important)
你遇到的问题本质是CSS选择器优先级冲突:Material-UI默认的选中行样式用了复合选择器 .MuiTableRow-root.Mui-selected(两个类名组合),优先级比你单独定义的 .rowSelected 类选择器高,所以你的自定义样式被覆盖了。用 !important 虽然能临时解决,但确实不是最优方案,下面给你两种更规范的解决思路:
方法一:利用Material-UI的样式嵌套语法(推荐)
Material-UI支持用&(指代当前类)和$className(指代同styles对象里的其他类)来编写嵌套样式,能完美匹配默认的选择器结构:
const styles = theme => ({ root: { // & 代表当前的root类,$selected 指代我们定义的selected类 '&$selected, &$selected:hover': { backgroundColor: theme.palette.grey[700], }, }, selected: {}, // 无需写样式,仅用于让$selected能被引用 }); class CustomTableRow extends React.Component { render() { const { classes, className, style } = this.props; return ( <TableRow component="div" selected={true} hover={true} className={className} classes={{ root: classes.root, selected: classes.selected, // 必须传入selected类才能让$selected生效 }} style={style} > {/* 子组件内容 */} </TableRow> ); } } export default withStyles(styles, { withTheme: true })(CustomTableRow);
这种写法生成的选择器和Material-UI默认的 .MuiTableRow-root.Mui-selected 优先级完全一致,而因为withStyles生成的样式会在默认Material-UI样式之后注入DOM,所以会优先生效。
方法二:直接匹配默认的Mui-selected类名
如果不想额外定义selected空类,也可以直接在root样式里匹配全局的.Mui-selected类:
const styles = theme => ({ root: { '&.Mui-selected, &.Mui-selected:hover': { backgroundColor: theme.palette.grey[700], }, }, }); class CustomTableRow extends React.Component { render() { const { classes, className, style } = this.props; return ( <TableRow component="div" selected={true} hover={true} className={className} classes={{ root: classes.root }} // 只需要传入root类即可 style={style} > {/* 子组件内容 */} </TableRow> ); } } export default withStyles(styles, { withTheme: true })(CustomTableRow);
这个思路和方法一原理一样,都是通过构造和默认样式优先级相同的选择器,利用样式注入顺序覆盖默认值,完全不需要!important。
为什么之前的写法无效?
你之前只定义了单独的rowSelected类,选择器优先级是10(单个类选择器),而Material-UI默认的.MuiTableRow-root.Mui-selected是两个类选择器,优先级是20,所以你的样式被默认样式覆盖了。上面两种方法构造的选择器优先级也是20,和默认样式持平,再靠注入顺序实现覆盖,这才是符合CSS规范的正确做法。
内容的提问来源于stack exchange,提问作者apporc
相关产品推荐
相关产品推荐

