17

I'm having a trouble of rendering pseudo before content dynamically in styled-components.

Am I doing something wrong?

I have no problem when I render pseudo before content statically, but it doesn't work when I try it dynamically.

React Component

const Test = (props) => {

    return (
        <Text before={12345}>
            {props.children}
        </Text>
    );

};

Styled Component(Not Work)

const Text = styled.span`

    &:before {
        content: ${props => {
            console.log(props.before); // I see '12345' in log.
            return props.before;
            }
    }


`;

Styled Component(This works fine)

const Text = styled.span`

    &:before {
        content: '12345'
    }


`;
  • It's not recommended to use dynamic content property with styled components as it will create new class for each content, if there are only a few different 'contents' you're fine, but if it can be anything you may have bad performance. – yairniz Jul 12 '20 at 11:43

3 Answers3

63

That is because content value must be within quotes in css

Example:

const Block = styled.div`
    &:before {
        display: absolute;
        top:0;
        content: '${props => props.before}'
    }
`

Please note that I am leveraging ES6 new features wherein a single statement function there is no need to use curly braces {} and return.

Codepen: https://codepen.io/metju/pen/zEKeOm

Matthew Barbara
  • 3,792
  • 2
  • 21
  • 32
  • 1
    Why do you have to wrap the expression in another quote, even if you are already returning a string? e.g. `content: ${props => props.test ? "foo" : " bar"};` fails `content: '${props => props.test ? "foo" : " bar"}';` works – henk May 18 '20 at 12:27
3

What I did is use the css helper function for this:

const Text = styled.span`
  &:before {
     ${props => !!props.before ?
      css`content: props.before;` : css`content: ' '';`
     };
  }
`
1

styled-components works the same as in sass, nothing different

const Text = styled.span`
    &:before {
       content: ${props => !!props.before ? props.before : " "};
    }

`;

I am a // renders: "I am a "

Reference taken from Before and After pseudo classes used with styled-components

Adeel Imran
  • 13,166
  • 8
  • 62
  • 77
  • I have used ```!!props.before```, this is a truthy statement which converts a string into a Boolean. Just to check if you are getting ```props.before``` or not. – Adeel Imran Sep 21 '17 at 08:41
  • Thank you for your help! But, it doesn't work... I tried this as well. &:before { content: ${props => !!props.before ? 'aaa' : "bbb"}; } Both 'aaa' and 'bbb' doesn"t get rendered. –  Sep 21 '17 at 10:15
  • Of course, as I mentioned in my post, If I write like this, it works. &:before { content: '12345' } –  Sep 21 '17 at 10:36