Theming, SSR & Performance
Theming & Global Styles
import { ThemeProvider, createGlobalStyle } from 'styled-components';
const theme = { primary: '#3498db', spacing: (n) => `${n * 8}px` };
const GlobalStyle = createGlobalStyle`
body { margin: 0; font-family: sans-serif; }
`;
function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<Button>Themed</Button>
</ThemeProvider>
);
}
const Button = styled.button`
background: ${(props) => props.theme.primary};
padding: ${(props) => props.theme.spacing(2)};
`;Runtime Cost & Style Caching
Styled-components computes and injects styles at RUNTIME as components render, adding JS overhead versus build-time-resolved CSS Modules/plain CSS — the trade-off behind newer "zero-runtime" CSS-in-JS alternatives. It caches generated CSS by resolved content, so multiple instances with identical resolved styles reuse one injected rule. Interpolating a value that changes on every render into effectively unique combinations (e.g. `left: ${mouseX}px` on every pixel of drag movement) defeats this caching — use a plain inline `style` attribute for that kind of continuous, high-frequency value instead.
Server-Side Rendering
import { ServerStyleSheet } from 'styled-components';
// Without this, a naive SSR setup serves HTML with no styles until
// client JS hydrates — a flash of unstyled content on first paint
const sheet = new ServerStyleSheet();
try {
const html = ReactDOMServer.renderToString(sheet.collectStyles(<App />));
const styleTags = sheet.getStyleTags(); // inject into the served HTML's <head>
} finally {
sheet.seal();
}Vendor Prefixing
styled-components automatically adds necessary vendor prefixes (-webkit-, etc.) to generated CSS via an embedded stylis-based mechanism — you generally don't need to write cross-browser prefixes by hand.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free