0Pricing
Frontend Academy · Lesson

CSS-in-JS: Styled-components and Emotion

Write component styles as tagged template literals with styled-components or the css prop with Emotion, and use props for dynamic styles.

CSS-in-JS: Styled-components and Emotion is a free Frontend Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is CSS-in-JS?

CSS-in-JS writes component styles directly in JavaScript/TypeScript. Styles are co-located with components, support dynamic values from props, and are automatically scoped. The two most popular libraries are styled-components and Emotion.

Styled-components Basics

Use tagged template literals to define styled components. The result is a React component that renders an HTML element with the styles applied.

import styled from 'styled-components';

const Button = styled.button`
  background: ${props => props.primary ? '#6366f1' : 'white'};
  color: ${props => props.primary ? 'white' : '#6366f1'};
  padding: 8px 16px;
  border: 2px solid #6366f1;
  border-radius: 4px;
  cursor: pointer;

  &:hover {
    opacity: 0.9;
  }
`;

<Button primary>Primary</Button>
<Button>Outline</Button>

Emotion — css Prop

Emotion's css prop applies styles to any JSX element. Requires the @emotion/react pragma or the Babel preset.

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';

function Card({ featured }: { featured?: boolean }) {
  return (
    <div css={css`
      padding: 16px;
      border-radius: 8px;
      border: ${featured ? '2px solid #6366f1' : '1px solid #e2e8f0'};
    `}>
      Content
    </div>
  );
}

Dynamic Styles from Props

Both libraries can read props to compute styles. This is their primary advantage over static CSS — no class-switching needed.

Theming with ThemeProvider

Styled-components and Emotion both support a ThemeProvider that injects theme values into all styled components.

import { ThemeProvider } from 'styled-components';

const theme = { colors: { primary: '#6366f1', bg: '#f7fafc' }, space: { sm: 8, md: 16 } };

<ThemeProvider theme={theme}>
  <App />
</ThemeProvider>

// Access in styled component:
const Card = styled.div`
  background: ${props => props.theme.colors.bg};
  padding: ${props => props.theme.space.md}px;
`;

Extending Styled Components

Extend an existing styled component to create a variant without duplicating styles.

const Button = styled.button`
  padding: 8px 16px;
  border-radius: 4px;
`;

const DangerButton = styled(Button)`
  background: #e53e3e;
  color: white;
`;

Global Styles

Use createGlobalStyle (styled-components) or Global (Emotion) for global CSS like body styles and resets.

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  *, *::before, *::after { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui; }
`;

<><GlobalStyle /><App /></>

Runtime Cost of CSS-in-JS

CSS-in-JS libraries inject styles at runtime via JavaScript. This adds CPU cost for parsing and style injection, plus JavaScript bundle size. Zero-runtime alternatives (vanilla-extract, linaria) generate static CSS at build time.

Zero-Runtime Alternatives

vanilla-extract: write styles in TypeScript, compiled to static CSS. linaria: CSS-in-JS syntax compiled to CSS Modules. Both give CSS-in-JS ergonomics without runtime overhead.

TypeScript with styled-components

Define a ThemeType and extend the DefaultTheme interface from styled-components for fully typed themes.

import 'styled-components';
import { theme } from './theme';

declare module 'styled-components' {
  export interface DefaultTheme extends typeof theme {}
}

When to Choose CSS-in-JS

CSS-in-JS is excellent for: dynamic styles driven by runtime JavaScript values, design systems with strong theming needs, teams that prefer JS-first workflows. The runtime cost is usually acceptable for non-performance-critical UIs.

Quick Check

What is the main trade-off of runtime CSS-in-JS libraries compared to static CSS solutions?

Recap: CSS-in-JS

Styled-components: tagged template literals, render a styled React element. Emotion: css prop or styled API. Dynamic styles from props eliminate class-switching. ThemeProvider injects theme values. createGlobalStyle for global CSS. Runtime cost is the main trade-off. Zero-runtime alternatives: vanilla-extract, linaria.

Frequently asked questions

Is the “CSS-in-JS: Styled-components and Emotion” lesson free?

Yes — the full text of “CSS-in-JS: Styled-components and Emotion” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.

What will I learn in “CSS-in-JS: Styled-components and Emotion”?

Write component styles as tagged template literals with styled-components or the css prop with Emotion, and use props for dynamic styles. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Frontend Academy?

No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “CSS-in-JS: Styled-components and Emotion” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Frontend Academy lesson?

Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. BEM Methodology: Block Element Modifier
  2. CSS Modules: Scoped Class Names
  3. CSS-in-JS: Styled-components and Emotion
  4. Tailwind CSS Utility-First Approach
← Back to Frontend Academy