CSS utilities provide helper functions for CSS composition, animations, and global styles. These functions enable advanced styling patterns and reusable style definitions.
The css helper function creates reusable CSS rule sets that can be shared between styled components or used in template literals.
function css<Props extends object>(
strings: TemplateStringsArray,
...interpolations: Interpolation<Props>[]
): RuleSet<Props>;
function css<Props extends object>(
styles: StyleFunction<Props> | StyledObject<Props>
): RuleSet<Props>;
type RuleSet<Props> = Interpolation<Props>[];Usage Examples:
import { css } from 'styled-components';
// Reusable style blocks
const centerContent = css`
display: flex;
align-items: center;
justify-content: center;
`;
const buttonBase = css`
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
`;
// Use in styled components
const CenteredButton = styled.button`
${buttonBase}
${centerContent}
background-color: #007bff;
color: white;
`;interface ButtonStyleProps {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'small' | 'medium' | 'large';
}
const buttonVariantStyles = css<ButtonStyleProps>`
background-color: ${props => {
switch (props.variant) {
case 'primary': return '#007bff';
case 'danger': return '#dc3545';
default: return '#6c757d';
}
}};
color: white;
&:hover {
opacity: 0.8;
}
`;
const buttonSizeStyles = css<ButtonStyleProps>`
padding: ${props => {
switch (props.size) {
case 'small': return '4px 8px';
case 'large': return '12px 24px';
default: return '8px 16px';
}
}};
font-size: ${props => {
switch (props.size) {
case 'small': return '12px';
case 'large': return '18px';
default: return '14px';
}
}};
`;
const Button = styled.button<ButtonStyleProps>`
border: none;
border-radius: 4px;
cursor: pointer;
${buttonVariantStyles}
${buttonSizeStyles}
`;interface ConditionalProps {
isActive?: boolean;
hasError?: boolean;
isLoading?: boolean;
}
const conditionalStyles = css<ConditionalProps>`
${props => props.isActive && css`
background-color: #28a745;
color: white;
`}
${props => props.hasError && css`
border-color: #dc3545;
background-color: #f8d7da;
`}
${props => props.isLoading && css`
opacity: 0.6;
cursor: not-allowed;
`}
`;
const ConditionalComponent = styled.div<ConditionalProps>`
padding: 10px;
border: 1px solid #ddd;
transition: all 0.2s ease;
${conditionalStyles}
`;Creates CSS keyframe animations that can be used in styled components.
function keyframes(
strings: TemplateStringsArray,
...interpolations: Interpolation<any>[]
): Keyframes;
interface Keyframes {
id: string;
name: string;
rules: string;
}Usage Examples:
import { keyframes } from 'styled-components';
const fadeIn = keyframes`
from {
opacity: 0;
}
to {
opacity: 1;
}
`;
const slideInLeft = keyframes`
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
`;
const FadeInDiv = styled.div`
animation: ${fadeIn} 0.3s ease-in;
`;
const SlideInDiv = styled.div`
animation: ${slideInLeft} 0.5s ease-out;
`;const bounce = keyframes`
0%, 20%, 53%, 80%, to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
transform: translate3d(0, 0, 0);
}
40%, 43% {
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
transform: translate3d(0, -30px, 0);
}
70% {
animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
transform: translate3d(0, -15px, 0);
}
90% {
transform: translate3d(0, -4px, 0);
}
`;
const pulse = keyframes`
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
`;
const AnimatedButton = styled.button`
padding: 12px 24px;
border: none;
border-radius: 6px;
background-color: #007bff;
color: white;
cursor: pointer;
&:hover {
animation: ${pulse} 0.6s ease-in-out;
}
&:active {
animation: ${bounce} 1s ease-in-out;
}
`;const createRotateAnimation = (degrees: number) => keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(${degrees}deg);
}
`;
const rotate360 = createRotateAnimation(360);
const rotate180 = createRotateAnimation(180);
const Spinner = styled.div`
width: 24px;
height: 24px;
border: 2px solid #f3f3f3;
border-top: 2px solid #007bff;
border-radius: 50%;
animation: ${rotate360} 1s linear infinite;
`;
const FlipIcon = styled.div`
transition: transform 0.3s ease;
&:hover {
animation: ${rotate180} 0.3s ease-in-out;
}
`;Creates a component that injects global CSS styles into the document head.
function createGlobalStyle<Props extends object>(
strings: TemplateStringsArray,
...interpolations: Interpolation<Props>[]
): React.ComponentType<ExecutionProps & Props>;Usage Examples:
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
margin: 0;
font-weight: 600;
}
a {
color: inherit;
text-decoration: none;
}
`;
// Usage in React
function App() {
return (
<>
<GlobalStyle />
<div>Your app content</div>
</>
);
}interface GlobalStyleProps {
theme: {
colors: {
background: string;
text: string;
primary: string;
};
fonts: {
main: string;
mono: string;
};
};
}
const GlobalStyle = createGlobalStyle<GlobalStyleProps>`
body {
background-color: ${props => props.theme.colors.background};
color: ${props => props.theme.colors.text};
font-family: ${props => props.theme.fonts.main};
}
code {
font-family: ${props => props.theme.fonts.mono};
background-color: rgba(0, 0, 0, 0.1);
padding: 2px 4px;
border-radius: 3px;
}
::selection {
background-color: ${props => props.theme.colors.primary};
color: white;
}
`;
// Usage with theme
<ThemeProvider theme={myTheme}>
<GlobalStyle />
<App />
</ThemeProvider>interface DynamicGlobalStyleProps {
isDarkMode?: boolean;
fontSize?: 'small' | 'medium' | 'large';
}
const DynamicGlobalStyle = createGlobalStyle<DynamicGlobalStyleProps>`
:root {
--background-color: ${props => props.isDarkMode ? '#1a1a1a' : '#ffffff'};
--text-color: ${props => props.isDarkMode ? '#ffffff' : '#333333'};
--font-size: ${props => {
switch (props.fontSize) {
case 'small': return '14px';
case 'large': return '18px';
default: return '16px';
}
}};
}
body {
background-color: var(--background-color);
color: var(--text-color);
font-size: var(--font-size);
transition: background-color 0.3s ease, color 0.3s ease;
}
${props => props.isDarkMode && css`
img {
filter: brightness(0.8);
}
`}
`;const sizes = {
mobile: '768px',
tablet: '1024px',
desktop: '1200px'
};
const media = {
mobile: (content: string) => css`
@media (max-width: ${sizes.mobile}) {
${content}
}
`,
tablet: (content: string) => css`
@media (max-width: ${sizes.tablet}) {
${content}
}
`,
desktop: (content: string) => css`
@media (min-width: ${sizes.desktop}) {
${content}
}
`
};
const ResponsiveComponent = styled.div`
padding: 20px;
${media.mobile`
padding: 10px;
font-size: 14px;
`}
${media.tablet`
padding: 15px;
font-size: 16px;
`}
${media.desktop`
padding: 30px;
font-size: 18px;
`}
`;const flexCenter = css`
display: flex;
align-items: center;
justify-content: center;
`;
const absoluteCenter = css`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
`;
const truncateText = css`
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
`;
const Card = styled.div`
${flexCenter}
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
`;
const Modal = styled.div`
${absoluteCenter}
background: white;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
`;
const Title = styled.h2`
${truncateText}
max-width: 300px;
`;const CSSReset = createGlobalStyle`
/* Modern CSS Reset */
*, *::before, *::after {
box-sizing: border-box;
}
* {
margin: 0;
}
html, body {
height: 100%;
}
body {
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
img, picture, video, canvas, svg {
display: block;
max-width: 100%;
}
input, button, textarea, select {
font: inherit;
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word;
}
#root, #__next {
isolation: isolate;
}
`;