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?
2 Answers
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
- React: CSS in JS (presentation by Christopher Chedeau, Facebook) (November 8, 2014)
- Writing your styles in JS ≠ writing inline styles (November 25, 2016)
Hope that helps! :)
Comments
While not exactly what I was hoping for originally, I did find a way to get this working. It turns out that the reason the translate3d(100%, 0, 0) wasn't working was because of flexbox. Once that was removed from the element, I was able to control the speed of the animation by setting the element width and the animation time by dynamically creating those styles in React.
-at the front of-webkit-animation:class="translate3d var30"could be something liketransform: translate3d(-30px, 0, 0);or whatever you're doing. It's not a good solution but without knowing 100% what you're trying to do can only guess.