Adding transitions to styled components

H. Doe picture H. Doe · Jun 9, 2017 · Viewed 14.1k times · Source

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.

Answer

chh picture chh · Jul 1, 2017

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);
  `};
`;