Styling React ComponentsEntry 5 of 7
Styled Components (CSS-in-JS)
A library (styled-components) that creates React components with styles attached, written in JavaScript template literals.
Notes
styled.inputfollowed by a template literal creates anInputcomponent that renders a styled<input>. The generated class name is unique, so styles are scoped.- Supports nesting, pseudo-selectors (
&:hover), and media queries. - Styles can depend on props: interpolate a function
${({ $invalid }) => ...}. - Prefix custom props with
$(transient props). Without the prefix, a prop likeinvalidis forwarded to the underlying DOM element, which triggers React warnings or sets unwanted attributes.$invalidis used for styling only and never reaches the DOM. - In TypeScript, pass the prop types as a generic:
styled.input<{ $invalid?: boolean }>`...`.
Status note: styled-components entered maintenance mode in 2025 and doesn't fit React Server Components. It's still common in existing codebases, but for new projects prefer CSS Modules or Tailwind.
What / Why / When
- What
Styled React components defined in JS.
- Why
Styles, logic, and props live together; dynamic styling is natural.
- When
Existing codebases that already use it, or design systems heavily driven by props.
- Use case
An
Inputwhose background turns red when invalid.
Code compare
npm install styled-componentsAngular has no CSS-in-JS equivalent because it doesn't need one: scoped styles plus class and style bindings cover the same ground. Build a small component whose input() drives a class:
import { Component, input } from "@angular/core";@Component({ selector: "app-email-field", template: ` <p> <label [class.invalid]="invalid()">Email</label> <input type="email" [class.invalid]="invalid()" /> </p> `, styles: ` label { display: block; margin-bottom: 0.5rem; font-size: 0.75rem; font-weight: 700; text-transform: uppercase; color: #6b7280; } label.invalid { color: #f87171; } input { width: 100%; padding: 0.75rem 1rem; line-height: 1.5; color: #374151; border: 1px solid transparent; border-radius: 0.25rem; background-color: #d1d5db; } input.invalid { border-color: #f73f3f; background-color: #fed2d2; } input:focus { outline: 2px solid #f59e0b; } `,})export class EmailFieldComponent { invalid = input(false);}Differences and gotchas
- The
$prefix has no Angular counterpart: inputs are never forwarded to the DOM automatically. - styled-components generates CSS at runtime; Angular component styles are compiled at build time.
Quick reference
| React (styled-components) | Angular |
|---|---|
const Input = styled.input`...` | Component with styles |
${({ $invalid }) => ...} | [class.invalid]="invalid()" |
$invalid transient prop | invalid = input(false) |
&:hover | :hover in component CSS |