0
# Keyframe Animations
1
2
System for creating and managing CSS keyframe animations in Radium with automatic vendor prefixing and global style injection.
3
4
## Capabilities
5
6
### keyframes Function
7
8
Creates keyframe animation objects that can be used with the `animationName` CSS property.
9
10
```javascript { .api }
11
/**
12
* Create a keyframes animation for use in inline styles
13
* @param keyframeRules - Object defining animation keyframes with percentages as keys
14
* @param name - Optional name prefix for debugging (added to generated animation name)
15
* @returns Keyframes object for use with animationName property
16
*/
17
function keyframes(
18
keyframeRules: { [percentage: string]: CSSProperties },
19
name?: string
20
): KeyframesObject;
21
22
interface KeyframesObject {
23
/** Internal marker identifying this as a keyframes object */
24
__radiumKeyframes: boolean;
25
/** Internal processing function for CSS generation */
26
__process(userAgent?: string): { animationName: string; css: string };
27
}
28
29
interface CSSProperties {
30
[property: string]: string | number;
31
}
32
```
33
34
**Usage Examples:**
35
36
```javascript
37
import Radium, { keyframes, StyleRoot } from 'radium';
38
39
// Basic keyframe animation
40
const fadeIn = keyframes({
41
'0%': { opacity: 0 },
42
'100%': { opacity: 1 }
43
});
44
45
// Complex animation with multiple properties
46
const slideAndFade = keyframes({
47
'0%': {
48
opacity: 0,
49
transform: 'translateX(-100px)'
50
},
51
'50%': {
52
opacity: 0.5,
53
transform: 'translateX(-50px)'
54
},
55
'100%': {
56
opacity: 1,
57
transform: 'translateX(0)'
58
}
59
}, 'slideAndFade'); // Optional name for debugging
60
61
// Use in component styles
62
const AnimatedComponent = () => (
63
<div style={styles.animated}>
64
Animated content
65
</div>
66
);
67
68
const styles = {
69
animated: {
70
// Use placeholder name in animation property
71
animation: 'x 2s ease-in-out',
72
// Assign keyframes object to animationName
73
animationName: fadeIn,
74
backgroundColor: 'blue',
75
height: '100px',
76
width: '100px'
77
}
78
};
79
```
80
81
### StyleRoot Requirement
82
83
Keyframe animations require components to be wrapped in `StyleRoot` for proper CSS injection.
84
85
```javascript { .api }
86
/**
87
* Required wrapper for keyframe animations
88
* Provides context for global style management
89
*/
90
const StyleRoot: React.ComponentType<{
91
children: React.ReactNode;
92
radiumConfig?: RadiumConfig;
93
}>;
94
```
95
96
**Usage Examples:**
97
98
```javascript
99
import { StyleRoot } from 'radium';
100
101
function App() {
102
return (
103
<StyleRoot>
104
<AnimatedComponent />
105
<AnotherAnimatedComponent />
106
</StyleRoot>
107
);
108
}
109
```
110
111
### Multiple Animations
112
113
Chain multiple keyframe animations by passing an array to `animationName`.
114
115
```javascript { .api }
116
interface MultipleAnimations {
117
animationName: KeyframesObject[];
118
animationDuration: string;
119
animationTimingFunction?: string;
120
animationIterationCount?: string;
121
animationDelay?: string;
122
}
123
```
124
125
**Usage Examples:**
126
127
```javascript
128
const pulseAnimation = keyframes({
129
'0%': { width: '10%' },
130
'50%': { width: '50%' },
131
'100%': { width: '10%' }
132
}, 'pulse');
133
134
const colorAnimation = keyframes({
135
'0%': { backgroundColor: 'red' },
136
'25%': { backgroundColor: 'yellow' },
137
'50%': { backgroundColor: 'green' },
138
'75%': { backgroundColor: 'blue' },
139
'100%': { backgroundColor: 'red' }
140
}, 'colorCycle');
141
142
const multiAnimationStyles = {
143
element: {
144
// Multiple animations
145
animationName: [pulseAnimation, colorAnimation],
146
animationDuration: '2s, 4s',
147
animationTimingFunction: 'ease-in-out, linear',
148
animationIterationCount: 'infinite, infinite',
149
height: '50px',
150
margin: '0 auto'
151
}
152
};
153
```
154
155
### Keyframe Percentages
156
157
Keyframe rules support various percentage formats and special keywords.
158
159
```javascript { .api }
160
interface KeyframePercentages {
161
/** Numeric percentages */
162
'0%': CSSProperties;
163
'25%': CSSProperties;
164
'50%': CSSProperties;
165
'100%': CSSProperties;
166
/** Special keywords */
167
'from': CSSProperties; // Same as 0%
168
'to': CSSProperties; // Same as 100%
169
}
170
```
171
172
**Usage Examples:**
173
174
```javascript
175
// Using percentages
176
const growAnimation = keyframes({
177
'0%': { transform: 'scale(1)' },
178
'25%': { transform: 'scale(1.1)' },
179
'50%': { transform: 'scale(1.2)' },
180
'75%': { transform: 'scale(1.1)' },
181
'100%': { transform: 'scale(1)' }
182
});
183
184
// Using from/to keywords
185
const simpleSlide = keyframes({
186
'from': { transform: 'translateX(0)' },
187
'to': { transform: 'translateX(100px)' }
188
});
189
190
// Mixed percentages
191
const complexBounce = keyframes({
192
'from': { transform: 'translateY(0)' },
193
'20%': { transform: 'translateY(-20px)' },
194
'40%': { transform: 'translateY(0)' },
195
'60%': { transform: 'translateY(-10px)' },
196
'80%': { transform: 'translateY(0)' },
197
'to': { transform: 'translateY(0)' }
198
});
199
```
200
201
### Vendor Prefixing
202
203
Keyframes are automatically vendor-prefixed based on the browser environment or provided user agent.
204
205
**Usage Examples:**
206
207
```javascript
208
// Animation with properties that need prefixing
209
const prefixedAnimation = keyframes({
210
'0%': {
211
transform: 'rotate(0deg)',
212
filter: 'blur(0px)'
213
},
214
'100%': {
215
transform: 'rotate(360deg)',
216
filter: 'blur(5px)'
217
}
218
});
219
220
// Generates vendor-prefixed CSS automatically:
221
// @-webkit-keyframes radium-animation-xyz { ... }
222
// @-moz-keyframes radium-animation-xyz { ... }
223
// @keyframes radium-animation-xyz { ... }
224
```
225
226
### Server-Side Rendering
227
228
For server-side rendering, provide user agent through configuration.
229
230
**Usage Examples:**
231
232
```javascript
233
// Server-side keyframes with user agent
234
const serverConfig = {
235
userAgent: req.headers['user-agent']
236
};
237
238
const ServerApp = () => (
239
<StyleRoot radiumConfig={serverConfig}>
240
<AnimatedComponent />
241
</StyleRoot>
242
);
243
```
244
245
## Animation Properties
246
247
### Standard Animation Properties
248
249
Use standard CSS animation properties alongside `animationName`.
250
251
```javascript { .api }
252
interface AnimationProperties {
253
animationName: KeyframesObject | KeyframesObject[];
254
animationDuration?: string;
255
animationTimingFunction?: string;
256
animationDelay?: string;
257
animationIterationCount?: string | number;
258
animationDirection?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
259
animationFillMode?: 'none' | 'forwards' | 'backwards' | 'both';
260
animationPlayState?: 'running' | 'paused';
261
}
262
```
263
264
**Usage Examples:**
265
266
```javascript
267
const rotateAnimation = keyframes({
268
'0%': { transform: 'rotate(0deg)' },
269
'100%': { transform: 'rotate(360deg)' }
270
});
271
272
const animationStyles = {
273
spinner: {
274
animationName: rotateAnimation,
275
animationDuration: '2s',
276
animationTimingFunction: 'linear',
277
animationIterationCount: 'infinite',
278
animationDirection: 'normal',
279
animationFillMode: 'none',
280
width: '50px',
281
height: '50px',
282
border: '3px solid #333'
283
}
284
};
285
```
286
287
## Generated CSS
288
289
Radium automatically generates unique animation names and injects CSS into the document.
290
291
**Example Generated CSS:**
292
293
```css
294
@keyframes radium-animation-abc123 {
295
0% { opacity: 0; transform: translateX(-100px); }
296
50% { opacity: 0.5; transform: translateX(-50px); }
297
100% { opacity: 1; transform: translateX(0); }
298
}
299
```
300
301
## Types
302
303
```javascript { .api }
304
interface KeyframesObject {
305
__radiumKeyframes: boolean;
306
__process(userAgent?: string): { animationName: string; css: string };
307
}
308
309
type KeyframeRules = {
310
[percentage: string]: CSSProperties;
311
};
312
313
interface AnimationConfig {
314
animationName: KeyframesObject | KeyframesObject[];
315
animationDuration?: string;
316
animationTimingFunction?: string;
317
animationDelay?: string;
318
animationIterationCount?: string | number;
319
animationDirection?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
320
animationFillMode?: 'none' | 'forwards' | 'backwards' | 'both';
321
animationPlayState?: 'running' | 'paused';
322
}
323
```