我一直在尝试将 styled-components 与 alpha 版本的 material-ui
一起使用根据文档,这应该可以开箱即用。
此代码:
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样式的顺序()。来自 styled-components 的样式在 MUI 样式之前注入,这使得它们的优先级较低。
有什么办法可以不使用
!important
来解决这个问题吗?
在当前版本(即非alpha)版本中,您所要求的确实需要
!important
基础:
“请注意,内联定义的 CSS 属性优先于 CSS 类中定义的属性。您需要使用 !important 来优先于内联样式。”
参考: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;
styled-components
一般来说与任何组件库兼容。当您编写 styled(AnotherComponent)
时,我们会获取该组件并注入自动生成的类名。这意味着本质上与写作 <AnotherComponent className="sc-asdf123" />
! 是一样的
当前版本的
material-ui
特别是自定义样式有点困难,因为它使用内联样式。来自 MaterialUI 文档:
请注意,内联定义的 CSS 属性优先于 CSS 类中定义的属性。您需要使用 !important 来优先于内联样式。
这意味着简单地使用
styled(MaterialButton)
是行不通的,因为传入的样式大多会被忽略。您需要提高样式的特异性以覆盖 material-ui
附带的内联样式。 (如果您不熟悉细节,这篇文章是一本关于特异性的很好的入门读物)
alpha 版本的答案
material-ui
当前 alpha 版本的
material-ui
已切换为在底层使用 JSS。 (JS 中的 CSS 不是内联样式,如 styled-components
)这意味着问题很可能是在默认 styled-components
样式之后注入 material-ui
样式。 (由JSS注入)
JSS 支持 自定义注入点,因此您可以在 HTML 的 HEAD 中添加
<!-- jss -->
注释,以确保 JSS 在 styled-components
注入 CSS 之前注入其 CSS?
当前版本的答案
material-ui
有两种方法可以提高
styled-components
注入样式的特异性,一种更乏味,另一种更“hacky”。第一个是在所有样式的末尾添加 !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
更不那么烦人。
现在我们可以使用
<!-- material-ui -->
来确保样式在其之后注入。
默认情况下,Material-UI 将查找名为的 html 注释来注入样式。通过调整此注释在 HTML 正文中的位置,您可以控制 CSS 规则应用于组件的顺序。 (参考)