Search code examples
reactjsstyled-componentsemotion

Is there a way to get css attribute from passed css object inside styled component?


Is there a way to get css attribute from passed css object inside styled component?

Works correctly if I do in this way.

const SquareWithProp = styled.div<{ size: number; }>`
    height: ${props => props.size}px; 
    width: ${props => props.size}px;
`

But I need something like this

// css object does not seem to exist here
const Square = styled.div`
    height: ${props => props.css.width}; 
    width: ${props => props.css.width};
`
const Component = () => {
    return (
        <>
            <SquareWithProp size={100}>test</SquareWithProp>
            <Square css={{ width: 100 }}>test</Square>
        </>
    )
}

Is there a way to retrieve css object inside styled component?


Solution

  • The css value is certainly passed through to the props, but you're running into problems with the Typescript interface.

    This is not necessarily a trivial problem – using Emotion and styled-components on the same component feels like it's going to cause more problems than it solves! – but it depends on what you're trying to do.

    If you just want to pass through CSS-style properties in the css prop so that you can do fun things with them in your styled component, then this is easily done and doesn't involve Emotion at all. You just have to declare the css prop on your styled component:

    const Square = styled.div<{ css: React.CSSProperties }>`
        // e.g. { props: { css: { width: "200px" } } }
        height: ${props => props.css.width};
        width: ${props => props.css.width};
    `;
    

    Instead of React.CSSProperties you can use the CSSObject type exported by Emotion – this is just familiar css-in-js property-value stuff.

    If though you're wanting to pass through the output of Emotion's css function then things are a lot less helpful. css returns a serialized chunk of styles, so you will no longer be able to access the width without parsing it yourself:

    const SquareWithEmotionCss = styled.div<{ css: SerializedStyles }>`
      // e.g. { props: { css: { styles: "width: 200px" } } }
      ${(props) => props.css.styles};
    `;
    

    Here's a sandbox with examples of the different approaches.