【问题标题】:Styling nested components using styled components使用样式化组件样式化嵌套组件
【发布时间】:2020-09-22 16:43:51
【问题描述】:

我使用样式化组件的时间很短。

目前我正在尝试对嵌套元素进行样式覆盖,但我无法理解我做错了什么。

所以我的结构是。

---------------Form.js----- ----------

import { FieldWrapper } from './FieldWrapper';

const Form = styled.form`
    /** my form styles **/
`;

const StyledFieldWrapper = styled(FieldWrapper)`
    /** my FieldWrapper styles **/

    input {
        /** input overrides **/
        padding-bottom: 0.8rem;
        height: 2rem;
        line-height: 2rem;
        box-sizing: content-box;
        background-color: pink !important; // added just for visibility
    }
`;

const MyForm = props => {
    return (
        <>
            <Form>
                <StyledFieldWrapper />
            </Form>
        </>
    );
}

export { MyForm }

---------------FieldWrapper.js----- ----------

const Div = styled.div`
    /** my div styles **/
`;

const Label = styled.label`
    /** my label styles **/
`;

const Input = styled.input`
    /** my input styles **/
`;

const FieldWrapper = props => {
    return (
        <Div>
            <Label>
                <Input />
            </Label>
        </Div>
    );
}

export { FieldWrapper }

现在我期望发生的是FieldWrapper.js 中的样式将被Form.js 中的StyledFieldWrapper 元素覆盖,但这不会发生,我不知道为什么。我在过去和这个项目中都有过这样的覆盖。同样StyledFieldWrapper 不仅包含覆盖,它也有自己的风格,我什至看不到这些。

有人遇到过类似的问题吗?

注意:我尝试使用Styling Nested Components in Styled-Components 中的解决方案,但没有成功。

【问题讨论】:

    标签: reactjs styled-components


    【解决方案1】:

    编辑:

    由于您希望将样式应用于自定义组件,因此您还需要手动将 styled-components 生成的 className 分配给该组件的顶级元素。比如:

    const FieldWrapper = props => {
      return (
        <Div className={props.className}>
          <Label>
            <Input />
          </Label>
        </Div>
      );
    }
    

    问题可能与CSS Specicifity 有关,这意味着FieldWrapper 中定义的原始css 样式比Form 中定义的“重要性”更高。如果您检查您的元素,您可能会看到两种样式都已应用,但前者优先于后者。

    解决这个问题的方法是对Form 组件中定义的每个输入样式使用!important 规则。另一种方法是向&lt;Input /&gt; 添加一个类并将您的样式定义为myClass.input。基本上任何会增加您要应用的规则的具体性的东西。

    有关如何执行此操作的更多信息,请参见上面的链接。另请查看Cascade and inheritance

    一旦您了解源顺序很重要这一事实,在某些时候您会遇到这样一种情况:您知道规则在样式表中稍后出现,但应用了更早的、冲突的规则。这是因为较早的规则具有更高的特异性——它更具体,因此被浏览器选择为应该为元素设置样式的规则。

    正如我们在本课前面所见,类选择器比元素选择器具有更大的权重,因此在类上定义的属性将覆盖直接应用于元素的属性。

    这里需要注意的是,虽然我们正在考虑选择器,以及应用于它们选择的事物的规则,但不会覆盖整个规则,只有相同的属性。


    选择器的特异性量是使用四个不同的值(或分量)来衡量的,可以认为是千、百、十和个——四列中的四个单个数字:

    1. 数千:如果声明位于样式属性(即内联样式)内,则在此列中得分。此类声明没有选择器,因此它们的特异性总是简单的 1000。
    2. 百分:对于包含在整体选择器中的每个 ID 选择器,在此列中得分 1。
    3. 十位:在此列中,对于包含在整体选择器中的每个类选择器、属性选择器或伪类,得分为 1。
    4. 一个:在此列中,每个元素选择器或包含在整体选择器中的伪元素都得一分。

    这是一个来自 MDN 的示例:

    /* specificity: 0101 */
    #outer a {
        background-color: red;
    }
    
    /* specificity: 0201 */
    #outer #inner a {
        background-color: blue;
    }
    

    【讨论】:

    • 特异性是我最初认为的问题所在(因此样式组件内的输入标签赋予它特异性)。我尝试了!important 并添加了FieldWrapper 中不存在的样式,并且在开发工具中都不可见。
    • @Comum 很有趣。您能否编辑您的帖子并包含相关样式?
    • 我已经编辑了样式,但我的印象是,它可能与我这边的样式组件相关,而不是特定样式。
    • 啊,您可能没有将生成的 className 应用于组件的顶级包装器。我会编辑我的回复。
    • 不,你是对的。我没有应用类名,但是这是如何通过的?因为我以前也看到过这个没有类名。
    猜你喜欢
    • 2019-11-08
    • 2020-09-26
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 2021-07-02
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多