问题
Focused, checked classes seems to not work properly. I need to always use !important or use jss styles provided by material-ui. For example:
https://codesandbox.io/s/css-modules-nvy8s?file=/src/CssModulesButton.js
CssModulesButton.module.css
.checkboxtest {
color: blue;
}
.checkboxtestworking {
color: blue !important;
}
CssModulesButton.js
import React from "react";
// webpack, parcel or else will inject the CSS into the page
import styles from "./CssModulesButton.module.css";
import Checkbox from "@material-ui/core/Checkbox/Checkbox";
export default function CssModulesButton() {
return (
<div>
<Checkbox classes={{ checked: styles.checkboxtest }}>testasd</Checkbox>
<Checkbox classes={{ checked: styles.checkboxtestworking }}>
testasd
</Checkbox>
</div>
);
}
index.js
import React from "react";
import { render } from "react-dom";
import { StylesProvider } from "@material-ui/core/styles";
import CssModulesButton from "./CssModulesButton";
import CssBaseline from "@material-ui/core/CssBaseline";
const App = () => <CssModulesButton />;
render(<App />, document.querySelector("#root"));
I cant overwrite Checkbox color in any other way than using !important. The problem persists when using classes={{focused:styles.focused}} and many others.
Is there a way to simply overwrite components with classes without !important? Sometimes even !important doesnt work
inb4 im using injectFirst
回答1:
You mentioned injectFirst
in your question, though your sandbox example wasn't using it. You should use it since this will make sure that the CSS from your CSS modules is inserted after the Material-UI CSS in the <head>
element. When specificity is the same, the styles that occur later will win over earlier styles.
The default styles for the checkbox colors are as follows:
colorSecondary: {
'&$checked': {
color: theme.palette.secondary.main,
'&:hover': {
backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.hoverOpacity),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
'&$disabled': {
color: theme.palette.action.disabled,
},
},
Below is the corresponding CSS generated by JSS:
.MuiCheckbox-colorSecondary.Mui-checked {
color: #f50057;
}
.MuiCheckbox-colorSecondary.Mui-disabled {
color: rgba(0, 0, 0, 0.26);
}
.MuiCheckbox-colorSecondary.Mui-checked:hover {
background-color: rgba(245, 0, 87, 0.04);
}
@media (hover: none) {
.MuiCheckbox-colorSecondary.Mui-checked:hover {
background-color: transparent;
}
}
The important aspect to notice is that the checked
style is done via two classes. In order to override these styles you need that same degree of specificity or greater.
Below is a full working example overriding the checked
color of the checkbox:
index.js (important part here is <StylesProvider injectFirst>
)
import React from "react";
import { render } from "react-dom";
import { StylesProvider } from "@material-ui/core/styles";
import CssModulesButton from "./CssModulesButton";
const App = () => (
<StylesProvider injectFirst>
<CssModulesButton />
</StylesProvider>
);
render(<App />, document.querySelector("#root"));
CssModulesButton.module.css
- Uses two classes in the style declaration -- the
checkboxtest
CSS module class andMui-checked
(the global class which Material-UI adds for the checked state)
.checkboxtest:global(.Mui-checked) {
color: blue;
}
CssModulesButton.js
import React from "react";
import styles from "./CssModulesButton.module.css";
import Checkbox from "@material-ui/core/Checkbox";
export default function CssModulesButton() {
return (
<div>
<Checkbox className={styles.checkboxtest} />
</div>
);
}
Follow-up question from the comments:
Could you explain why can't I use classes? Shouldn't
classes={{checked:styles.AnyClass}}
overwrite the styles successfully? I understand why it doesn't, but what is the purpose of classes then?
You can use the classes
prop, but there isn't any compelling reason to do so in this case. The following will also work, so long as the declaration for the styles is the same (using two CSS classes) so that you have the appropriate degree of specificity:
<Checkbox classes={{ checked: styles.checkboxtest }} />
As far as the second part of your question ("what is the purpose of classes then?"), there are two main reasons to use the classes
prop. Some of the CSS classes for the classes
prop get applied to different elements within the component, and some only get applied when the component is in a particular state, or when certain props have been used on the component. In this case, you are trying to target these styles for a particular state of the component. In v3 of Material-UI, you would have needed to use the classes
prop to provide a class name that would only be applied for the checked
state, but in v4 Material-UI switched to using global class names for these states (more details here: https://material-ui.com/customization/components/#pseudo-classes) such as Mui-checked
. This makes it easier to target these states via a single generated class (a big driver of this change was to make it easier to customize Material-UI components using styled-components
).
来源:https://stackoverflow.com/questions/61827031/how-to-overwrite-styles-with-classes-and-css-modules