peter flanagan
peter flanagan

Reputation: 9830

target first-child css styled-components

I am using styled-components and want to target the first child of Text, but am unable to do so.

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

Upvotes: 23

Views: 120531

Answers (6)

try using the style with the HTML tag you want to style, In your case, it would be:

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

Upvotes: -1

superluminary
superluminary

Reputation: 49232

This is possible, but probably not correct

This totally is possible, as we see with the other answers. The issue is that with first-child or nth-child solutions you tend to end up reaching down the DOM hierarchy, creating all sorts of specificity issues that can be difficult to untangle later.

The beauty of Styled Components is you typically apply styles to the element itself, meaning your styles stay tightly coupled to your components. Components become portable, and it's easy to find the line of CSS that might be causing an issue in a complex app.

for example, if I were to style the first <a> in a list item in a ul differently, I'd need to put :first-child further up the hierarchy, breaking encapsulation.

Treat your styles as a function

The simple solution to this is to recognise that the styled component is a function that can receive parameters:

<StyledListItem index={index} />

Then receive that parameter in the component:

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 facilitates these kinds of programmatic solutions, and your life will be easier if you leverage them.

Upvotes: 0

Dagar
Dagar

Reputation: 241

Use like this

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

Upvotes: 24

kuubson
kuubson

Reputation: 189

it's better to use :last-of-type on certain styled component instead of using :nth-child and it works perfectly

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

Upvotes: 4

Arun AK
Arun AK

Reputation: 4370

Finally, I got your issue. The styled component confuses with the first two native p tag (from my perspective) and that's the reason why the CSS is not applied.

I will use a workaround like this:

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

By doing this, you are selecting the third child (which include the first two p tag) for the CSS

OR, you can do something like this: Adding a class name for the tag and giving CSS for that class.

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>

Here is the demo

Hope it helps :)

Upvotes: 32

dan
dan

Reputation: 1364

There shouldn't be a space between the & and the :first-child

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

Upvotes: 11

Related Questions