Search code examples
javascriptreactjsstyled-components

Styled components nested rules don't work


Here is my folder structure:

type/
- Heading.js
- index.js

card/
- Card.js
- CardGroup.js
- index.js

JSX:

<CardGroup>
  <Heading>...</Heading>
  <Card>...</Card<
</CardHeading>

Now I am trying to style the Heading and Card components differently if they are nested inside a CardGroup. CardGroup.js:

import Heading from '../type';
import Card from './Card';

const CardGroup = styled.div`
  ${Heading} { ... }
  ${Card} { ... }
`;

Works OK for the Heading but NOT for the Card. I came accross this issue before and I can't wrap my head around what's causing this. Is it because the are in the same folder? Is it because of the order they are imported in my app? Any ideas would be really helpful.

Updated:

My Card.js implementation:

const StyledCard = styled.div`...`;

const Card = props => {
  ...
  <StyledCard {...props}>{props.children}</StyledCard>
}

Solution

  • You need to target the component generated by styled-component (StyledCard in your example).

    // Card.js
    const ContainerCard = styled.div`
      width: 50px;
      height: 50px;
    `;
    
    const Card = ({ className }) => {
      return <ContainerCard className={className} />;
    };
    
    // Use any valid prop, Card.StyledComponent, Card.Style etc.
    Card.className = ContainerCard;
    export default Card;
    
    // App.js
    const Container = styled.div`
      height: 100vh;
      width: 100vw;
    `;
    
    // Styling custom components, through className prop.
    const VioletredRedCard = styled(Card)`
      background-color: palevioletred;
    `;
    
    
    // Target the component generated by styled-components
    const CardWrapper = styled.div`
      ${Card.className} {
        width: 100px;
        height: 100px;
        background-color: paleturquoise;
      }
    `;
    
    
    const App = () => {
      return (
        <Container>
          <CardWrapper>
            <Card />
          </CardWrapper>
          <VioletredRedCard />
        </Container>
      );
    };
    

    And, of course, if you want to style the card via: styled(Card), be sure you pass the className prop like in the example above.

    Edit elated-ganguly-zz3qz