Search code examples
csscss-selectorsstyled-components

How to target the nth-of-type of an element using styled-components


I have this styled-component. I would like to target the 2nd <Badge /> via css and styled-components however I cannot get it to work. I have tried multiple ways, but still I'm stuck.

//... maps through data and produces 2 cards with their title, price and discount (Badge)

        <CardContainerText>
          <CardTitle>{t(`${product.productName}`)}</CardTitle>{" "}
          <CardPrice>{t(`${totalPrice}€ / an`)}</CardPrice>
          {rate.amount > 0 && <Badge>Discount {rate.amount}% </Badge> }          </CardContainerText>
      </CardHeading>

This will produce the following html.

<div> CARD 1
  <h1>card title</h1>
  <p>card price</p>
  <span>card badge</span>
</div>
<div> CARD 2
  <h1>card title 2</h1>
  <p>card price 2</p>
  <span>card badge 2</span>
</div>

I will like to target card badge 2 with style-components so I can style it properly.

My <Badge /> css looks like this:

export const Badge = styled.span`
  display: inline-block;
  position: relative;
  top: -233px;
  right: 61px;
  padding: 14px;
  transform: rotate(-45deg);

  @media (min-width: 740px) {
    top: -68px;
    right: 150px;
    padding: 8px;

  [ASK]: Here I want that the second badge has a different top position. But this does not work.
    &:nth-of-type(2n) {
      top: -95px;
    }
  }
`

Solution

  • You could look at this a bit different: you want the Badge in the 2nd CardContainerText to have different styling

    export const Badge = styled.span`
      display: inline-block;
      position: relative;
      top: -233px;
      right: 61px;
      padding: 14px;
      transform: rotate(-45deg);
    
      @media (min-width: 740px) {
        top: -68px;
        right: 150px;
        padding: 8px;
      }
    `;
    
    const CardContainerText = styled.div`
      &:nth-of-type(2n) { /* this matches all even (2nd) CardContainerText */
        @media (min-width: 740px) {
          ${Badge} {  /* this matches the Badge in the 2nd container for yor media query */
            top: -95px;
          }
        }
      }
    `;
    
    

    This uses styled-components ability to refer other components