Adding transitions to styled components
Solution 1
You can try passing a conditional props to the component.
import styled, { css } from 'styled-components';
<Button expanded={ this.state.expanded } />
And then in you SC:
const Button = styled.div`
transform: rotate(0deg);
transition: transform .2s ease-out;
${ props => props.expanded && css`
transform: rotate(45deg);
`};
`;
Solution 2
You can also use a ternary operator:
const Button = styled.div`
transform: ${props => props.expanded ? 'rotate(180deg)' : 'rotate(0deg)'};
transition: transform .2s ease-out;
`;
Also make sure to define the Button outside the function you are using it in. Made that mistake right now, and didn't understand why the transition didn't work (tips for future me).
Solution 3
I was struggling with this for a while, I got it to work by doing this:
import styled from 'styled-components';
import { IconButton } from '@material-ui/core';
import { Pin } from 'styled-icons/boxicons-solid/Pin';
const IconWrapper = styled(IconButton).attrs(props => ({
style: {
padding: '0',
transition: 'transform 0.2s ease-out',
transform: props.rotated ? 'rotate(0)' : 'rotate(90deg)',
},
}))`
/* additional css goes here */
`;
Then in the return:
<IconWrapper
rotated={isRotated}
onClick={handleClick} /* toggle isRotated true/false */
>
<Pin size="20" />
</IconWrapper>
Related videos on Youtube
H. Doe
Updated on December 30, 2020Comments
-
H. Doe over 3 years
I have following component in React:
const Button = styled.div` width: 30px; height: 30px; position: absolute; right: 2em; top: 50%; transform: translateY(-50%); padding: 0; margin: 0; &::before, &::after { content: ""; position: absolute; background-color: #3d3935; transition: transform 0.25s ease-out; } &::before { top: 0; left: 50%; width: 4px; height: 100%; margin-left: -2px; } &::after { top: 50%; left: 0; width: 100%; height: 4px; margin-top: -2px; } `;
It just renders a component with library Styled-components. It basically shows a
+
sign.But then, I would like to rotate each of the lines separately, using:
&::before { transform: rotate(${this.state.expanded ? '0' : '45'}deg); } &::after { transform: rotate(${this.state.expanded ? '0' : '135'}deg); }
And it works great, but unfortunately there are no transitions (it happens immediately). Tried to include transitions in each of these lines, but it still doesn't affect the changes.
Another solution which I've tried was to add a class, e.g.
rotated
:&.rotated::before { transform: rotate(45deg); }
But styled components doesn't provide actually possibility to change classes dynamically using just it's logic.
Looking forward for any kind of help, thank you.
-
Morpheus almost 7 yearsApply transition to the element itself, not the pseudo element. You do a transform on the element, but applying a transition to pseudo.
-
H. Doe almost 7 years@Morpheus Tried, didn't work :(
-
Morpheus almost 7 yearsI wonder if introducing the initial transform value would help, something like this jsfiddle.net/uhqx7enc
-
-
judehall over 6 years+1 ${ props => props.expanded && css` transform: rotate(45deg);`}; Took me forever to find this. Thanks!