Styled Components
02 / 02

Theming, SSR & Performance

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