css Prop, styled API & Dynamic Styling
Why CSS-in-JS
Styles live in JS alongside the component, scoped automatically via generated hashed class names — solving the classic global-CSS-namespace-collision problem without manual unique naming. The tradeoff versus plain CSS/CSS Modules: some runtime overhead generating styles in the browser, in exchange for using live JS values directly in styles.
css Prop vs. styled
/** @jsxImportSource @emotion/react */
const Box = () => <div css={{ color: 'blue', padding: 8 }}>Hello</div>;
import styled from '@emotion/styled';
const Button = styled.button`
background: ${props => props.variant === 'primary' ? 'blue' : 'gray'};
padding: 8px 16px;
`;
<Button variant="primary">Save</Button>css prop styles inline, per-usage (needs the Babel plugin, or the @emotion/react JSX pragma). styled creates a distinct, reusable component with styling baked in — better for components reused with consistent styling across many places. Both support prop-driven dynamic styling, something static CSS can't directly express.
Reusable css() Values & Composition
import { css } from '@emotion/react';
const baseButton = css`padding: 8px 16px; border-radius: 4px;`;
const disabledButton = css`opacity: 0.5; cursor: not-allowed;`;
<button css={[baseButton, isDisabled && disabledButton]}>Save</button>css() creates a standalone, importable style value; composing an array of styles avoids duplicating the base style for every variant combination.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free