Search code examples
javascriptcssreactjscss-animationskeyframe

Is there any way to pass a variable from ReactJS to a CSS stylesheet?


I'm writing a scrolling ticker with a variable number of components, so I need it to change how far translate3d moves it based on the number of components. The only way I can think to do this is to somehow pass it a number from the JSX file, but I can't find a way to do that. Is there any way to pass the CSS a variable, or some other way to do what I'm wanting?


Solution

  • There are several « CSS in JS » libraries which allows you to add keyframes to your components animations. As you write your styles in your JavaScript, you can directly use your components props/states or some other constants to create your components styles.

    The 3 following libraries have a keyframes support (I've personally been using the first one):

    Styled-Components (GitHub)

    import styled, { keyframes } from 'styled-components';
    
    const rotate360 = keyframes`
      from { transform: rotate(0deg); }
      to { transform: rotate(360deg); }
    `;
    
    const Rotate = styled.div`
      display: inline-block;
      animation: ${rotate360} 2s linear infinite;
    `;
    

    Glamor (GitHub)

    import { css } from 'glamor'
    
    let bounce = css.keyframes('bounce', {
      '0%': { transform: 'scale(0.1)', opacity: 0 },
      '60%': { transform: 'scale(1.2)', opacity: 1 },
      '100%': { transform: 'scale(1)' }
    })
    
    <div {...css({
      animation: `${bounce} 2s`,
      width: 50, height: 50,
      backgroundColor: 'red'
    })}>
      bounce!
    </div>
    

    Aphrodite (GitHub)

    const translateKeyframes = {
      '0%': { transform: 'translateX(0)' },
      '50%': { transform: 'translateX(100px)' },
      '100%': { transform: 'translateX(0)' },
    };
    
    const opacityKeyframes = {
      'from': { opacity: 0 },
      'to': { opacity: 1 }
    };
    
    const styles = StyleSheet.create({
      zippyHeader: {
        animationName: [translateKeyframes, opacityKeyframes],
        animationDuration: '3s, 1200ms',
        animationIterationCount: 'infinite',
      },
    });
    
    <div className={css(styles.zippyHeader)}>...</div>
    

    More reading about the « CSS in JS » pattern

    Hope that helps! :)