目标元素的第一个子元素CSS样式化组件

22

我正在使用 styled-components 并想要定位到 Text 的第一个子元素,但是无法实现。


const Text = styled.p`
    font-size: 12px;
    &:first-child {
        margin-bottom: 20px;
    }
`;

... component

return(
   <div>
      <p>I am just regular text</p>
      <p>Me too</p>
      <Text>Hello Joe</Text> // this should have the margin bottom
      <Text>Goodbye</Text >
   </div>
)
6个回答

31

最后,我理解了你的问题。从我的角度来看,styled component 和前两个本地的p标签混淆了,这就是CSS未应用的原因。

我将使用以下解决方法:

const Text = styled.p`
    font-size: 12px;
    color: blue;
    &:nth-child(3) {
        margin-bottom: 20px;
        color: red !important;
    }
`;

通过这样做,您正在选择第三个子元素(其中包括前两个p标签)的CSS。

或者,您可以像这样做:为标签添加类名并为该类提供CSS。

const Text = styled.p`
  font-size: 12px;
  color: blue;
  &.colors {
    margin-bottom: 20px;
    color: red !important;
  }
`;

 <div>
    <p>I am just regular text</p>
    <p>Me too</p>
    <Text className="colors">Hello Joe</Text>
    <Text>Goodbye</Text>
</div>

这是演示,希望对您有所帮助 :)


我稍微更新了我的问题,p标签内有一个span,这会导致它不起作用吗?很抱歉之前没有包含这个信息。另外,当我使用你的代码时,所有内容都是蓝色的,所以首个子元素选择器似乎不起作用。 - peter flanagan
好奇怪,这里还是不起作用。无论如何,我会给你们两个点赞的。 - peter flanagan
@Thinker 哈哈,我写了几乎完全相同的话,并提供了一个使用两种不同颜色的演示。我想我们可能是 CSS 灵魂伴侣,开个玩笑.. :D - dschu
您能检查一下更新的问题吗?这就是为什么它出错的原因。 - peter flanagan
@peterflanagan 您是正确的。现在我明白了问题所在。这是因为前两个 p 标签。我已经更新了我的解决方案。希望能有所帮助 :) - Arun AK

21

像这样使用

const Text = styled.p`
   font-size: 12px;
    > * {
      &:first-child {
         margin-bottom: 20px;
      }
    }
`;

10
这很有效,不过更新回答并说明其原理会更加有用。 - Dan
这是因为React还是因为CSS的原因呢? - Jake Smith

10

&:first-child之间不应有空格。

&:first-child {
    margin-bottom: 20px;
}

这也是我想的,而且我也尝试过了,但它不起作用。 - peter flanagan
奇怪。字体大小属性应用正常吗? - dan
我稍微更新了一下我的问题,p标签内还有一个span元素,这是否与它没有正常工作有关?非常抱歉之前没有包含这个信息。 - peter flanagan
@dan是正确的,是空格的问题。请查看此演示:一切都正常:https://codesandbox.io/s/8882z34y19 - dschu
你能检查一下更新后的问题吗?这就是为什么它不正确的原因。 - peter flanagan

4
最好在某些样式化组件上使用:last-of-type而不是使用:nth-child,这样效果更加完美。
export default styled.div`
    :last-of-type {
        background: red;
    }`

const Text = styled.p`
    font-size: 12px;
    color: blue;
    &:nth-child(3) {
        margin-bottom: 20px;
        color: red !important;
    }
`;


我喜欢last-of-type的方法。这种方法更加模块化(例如,组件样式保持特定于元素本身,而不是干扰子元素)。 - vincent

0

这是可能的,但可能不正确

正如我们在其他答案中看到的那样,这完全是可能的。问题在于使用first-child或nth-child解决方案时,您往往会深入DOM层次结构,从而创建各种特定性问题,这些问题稍后可能很难解开。

Styled Components的美妙之处在于,您通常将样式应用于元素本身,这意味着您的样式与组件紧密耦合。组件变得可移植,很容易找到可能在复杂应用程序中引起问题的CSS行。

例如,如果我要以不同的方式为ul中列表项中的第一个进行样式设置,则需要将:first-child放置在更高的层次结构中,从而破坏封装。

将样式视为函数

解决此问题的简单方法是认识到styled component是可以接收参数的函数:

<StyledListItem index={index} />

然后在组件中接收该参数:

export const StyledListItem = styled.li<{index?: number}>`
  ${
    ({index}) => {
      if (index === 3) return `
        color: red;
        border: 2px dotted pink;
      `
      if (index === 0) return `
        border-left: none
      `
    }
  }
`

CSS in JS 可以方便地实现这些编程解决方案,如果您利用它们,您的生活将更加轻松。


0
尝试使用您想要样式化的HTML标签的样式, 在您的情况下,应该是:

p:first-child {
// your style here
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接