reactjs 如何正确使用material-ui(alpha)和styeld-components?

w41d8nur  于 2023-06-22  发布在  React
关注(0)|答案(3)|浏览(201)

我一直尝试在alpha版本的material-ui中使用styled-components
根据documentation,这应该是开箱即用的。
此代码:

const StyledButton = styled(Button)`
   color: red;
   text-transform: uppercase;
`;

return <StyledButton>Button</StyledButton>;

会产生这样的结果:

<button tabindex="0" class="MuiButtonBase-root-3177716317 sc-bdVaJa sxRGN" type="button" role="button">
...
</button>

看起来不错
然而,我遇到的唯一问题是注入的CSS样式的顺序pic)。样式组件中的样式在MUI的样式之前注入,这使得它们的优先级较低。
有没有办法不使用!important来解决这个问题?

cotxawn7

cotxawn71#

在当前版本中(即non-alpha)版本,您所要求的确实需要!important基础:
“请注意,内联定义的CSS属性优先于CSS类中定义的属性。你需要使用!重要的是要优先于内联样式。”
参考:http://www.material-ui.com/#/customization/styles
也许alpha版本还没有完全摆脱这种内联需求,或者它仍然是一个正在进行的工作。
为了克服这种情况,我自己所做的是(不幸的是)在需要这样的解决方案时,在标准<button>元素上重新创建整个CSS。下面是一个例子,说明我是如何使用react-photonkit“主题”来实现这一点的。

// @flow
import styled from 'styled-components';

const PhotonStyledButton = styled.button`
  font-family: Arial, Roboto, Helvetica, sans-serif;
  height: 30px;
  display: inline-block;
  padding: 6px 12px;
  margin-bottom: 0;
  font-size: 12px !important;
  line-height: 1.4;
  text-align: center;
  white-space: nowrap;
  vertical-align: middle;
  cursor: default;
  background-image: none;
  border: 1px solid transparent;
  border-radius: $default-border-radius;
  box-shadow: 0 1px 1px rgba(0,0,0,.06);
  -webkit-app-region: no-drag;

  &:focus {
    outline: none;
    box-shadow: none;
  }

  color: #333;
  border-top-color: #c2c0c2;
  border-right-color: #c2c0c2;
  border-bottom-color: #a19fa1;
  border-left-color: #c2c0c2;
  background-color: #fcfcfc;
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fcfcfc), color-stop(100%,#f1f1f1));
  background-image: -webkit-linear-gradient(top, #fcfcfc 0%, #f1f1f1 100%);
  background-image: linear-gradient(to bottom, #fcfcfc 0%, #f1f1f1 100%);

  &:active {
    background-color: #ddd;
    background-image: none;
  }
`;

export default PhotonStyledButton;
q5iwbnjs

q5iwbnjs2#

styled-components通常与任何组件库兼容。当你编写styled(AnotherComponent)时,我们使用该组件并注入一个自动生成的类名。这意味着本质上它和编写<AnotherComponent className="sc-asdf123" />是一样的!
material-ui的当前版本特别难以自定义样式,因为它使用内联样式。根据MaterialUI文档:
请注意,内联定义的CSS属性被赋予优先于CSS类中定义的属性。你需要使用!重要的是要优先于内联样式。
这意味着简单地使用styled(MaterialButton)是行不通的,因为传入的样式大多会被忽略。您需要提高样式的特殊性,以覆盖material-ui附带的内联样式。(如果你不熟悉细节,this article是一个很好的特异性引物)

material-ui的alpha版本答案

目前的alpha版本的material-ui已经切换到在引擎盖下使用JSS。(即CSS in JS not inline styles,如styled-components)这意味着问题很可能是styled-components样式在默认material-ui样式之后注入。(由JSS注入)
JSS支持自定义注入点,所以你可以在HTML的HEAD中添加一个<!-- jss -->注解,以确保JSS在styled-components注入CSS之前注入CSS?

当前版本material-ui的答案

有两种方法可以提高styled-components注入样式的特异性,一种更乏味,另一种更“黑客”。第一个是在所有样式的末尾添加!important

const Button = styled(MaterialButton)`
  color: blue!important;
`

虽然这在大多数情况下是有效的,但当组件中有很多自定义样式时,它会很快变得乏味。更好的方法是使用类名hack:

const Button = styled(MaterialButton)`
  &&& {
    color: blue;
  }

`

这些与符号被自动生成的类名替换,这意味着输出的CSS看起来像这样:

.sc-asdf123.sc-asdf123.sc-asdf123 {
  color: blue;
}

这大大地影响了特定性,从而覆盖了定义的内联样式,并且比必须在每个规则后面加上!important更烦人。

3pvhb19x

3pvhb19x3#

现在我们可以使用<!-- material-ui -->来确保样式在它之后注入。
默认情况下,Material-UI将查找一个名为的html注解以注入样式。通过调整此注解在HTML正文中的位置,您可以控制CSS规则应用于组件的顺序。(ref

相关问题