覆寫 Material-UI component CSS

EugeneChen
6 min readJul 22, 2018

--

Material-UI 提供了許多好用的 component 使用,但有時想要改掉它的樣式,該如何做呢?

我們只提 Overriding with classes ,因為 component 常常是自己組裝出來的

文件 Overrides 提供了很多方法使用,有興趣的人可去看看。

為了方便實驗,我們組裝一個 AgencyCard 的 component

// components/AgencyCard.js
import React from ‘react’;
import PropTypes from ‘prop-types’;
import { withStyles } from ‘@material-ui/core/styles’;
const styles = {
root: {
backgroundColor: 'red',
},
card: {
minWidth: 275,
},
};
function AgencyCard(props) {
const { classes } = props;
return (
<div className={classes.root}>
<p className={classes.card}>agency name</p>
</div>
);
}
AgencyCard.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(AgencyCard);

AgencyCard提供了兩個classes 的鍵 (root, card),就是官方文件說的 CSS API ,以 Button 的CSS API 就有提供一堆鍵(root, label, text, textPrimary …)。

錯誤寫法

現在的問題是如何覆寫它們,直覺上會直接寫

import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';
import AgencyCard from './Card/AgencyCard';const styles = () => ({});
class AgencyBox extends React.Component {
render() {
const {classes} = this.props;
return (
<div>
<AgencyCard classes={{
root: {
backgroundColor: 'blue', // <---- Error
}
}} />
</div>);
}
}
AgencyBox.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(AgencyBox);

會出現以下錯誤

正確寫法

正確要是

import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';
import AgencyCard from './Card/AgencyCard';const styles = () => ({
myCard: {
backgroundColor: 'blue',
},
});
class AgencyBox extends React.Component {
render() {
const {classes} = this.props;
return (
<div>
<AgencyCard classes={{
root: classes.myCard // <---- OK
}} />
</div>);
}
}
AgencyBox.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(AgencyBox);

這是因為 classes 在送到 component 中後就變成 key -> class name 的object,例如:

classes =
{
root:"AgencyCard-root-145",
card:"AgencyCard-card-146"
}

因此,要用CSS 注入 (CSS injection),配合 withStyles() 覆寫 AgencyCard classes 的 root。

你可以在 AgencyCard 印出 classes ,你會發現classes 只是的鍵值都是字串

回到原來的問題:覆寫 Material-UI component CSS

覆寫 Button 的 root CSS API

import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
const styles = () => ({
myButtonRoot: {
backgroundColor: 'blue',
},
});
class AgencyBox extends React.Component {
render() {
const {classes} = this.props;
return (
<div>
<Button classes={{
root: classes.myButtonRoot
}} />
</div>);
}
}
AgencyBox.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(AgencyBox);

參考資料

https://material-ui.com/customization/css-in-js/#withstyles-styles-options-higher-order-component

https://material-ui.com/customization/overrides/#overriding-with-classes

--

--