如何用 类 和 css 模块覆盖样式?

How to overwrite styles with classes and css modules?

重点,检查类好像不能正常工作。 我需要始终使用 !important 或使用 material-ui 提供的 jss 样式。 例如:

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"));

除了使用 !important,我无法以任何其他方式覆盖复选框颜色。 使用 类={{focused:styles.focused}} 和许多其他时问题仍然存在。

有没有办法不用 !important 简单地用 类 覆盖组件?有时甚至 !important 也不起作用

inb4 即时通讯使用 injectFirst

您在问题中提到了 injectFirst,但您的沙箱示例并未使用它。您应该使用它,因为这将确保 CSS 模块中的 CSS 插入到 [=17= 中的 Material-UI CSS 之后] 元素。当specificity相同时,后出现的样式将胜过早出现的样式。

复选框颜色的default styles如下:

  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,
    },
  },

下面是JSS生成的对应CSS:

.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;
  }
}

需要注意的重要方面是 checked 样式是通过两个 class 样式完成的。为了覆盖这些样式,您需要相同程度或更高程度的特异性。

下面是覆盖复选框 checked 颜色的完整工作示例:

index.js(这里重要的部分是<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

  • 在样式声明中使用了两个 class——checkboxtest CSS 模块 class 和 Mui-checked(全局 class其中 Material-UI 添加为检查状态)
.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>
  );
}


来自评论的后续问题:

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?

您可以使用 classes 道具,但在这种情况下没有任何令人信服的理由这样做。以下内容也适用,只要样式的声明相同(使用两个 CSS classes)以便您具有适当的特异性程度:

<Checkbox classes={{ checked: styles.checkboxtest }} />

就你问题的第二部分 ("what is the purpose of classes then?") 而言,使用 classes 道具有两个主要原因。 classes 道具的一些 CSS class 应用于组件内的不同元素,而一些仅在组件处于特定状态或某些道具具有时才应用在组件上使用。在这种情况下,您试图将这些样式定位到组件的特定状态。在 Material-UI 的 v3 中,您需要使用 classes 属性来提供仅适用于 checked 状态的 class 名称, 但在 v4 Material-UI 中切换为使用这些状态的全局 class 名称(此处有更多详细信息:https://material-ui.com/customization/components/#pseudo-classes),例如 Mui-checked。这使得通过单个生成的 class 更容易定位这些状态(此更改的一个重要驱动因素是使用 styled-components 更容易自定义 Material-UI 组件) .