Media queries in Emotion
Media queries can sit inside an Emotion style block, next to the rules they change, so responsive styles stay with the element.
How it works
- Media queries in the template. The
gridstyle sets three columns, and two@media (max-width: ...)blocks switch to two and one column. [1] - Show the active breakpoint. The
labelstyle sets&::aftercontent, and each media block overrides it, so the text names the layout in use. [1] - Why jsx() is called directly. The README uses the
/** @jsx jsx */pragma so JSX goes through Emotion'sjsx. This editor compiles JSX with React's own runtime, so the example callsjsx(type, props, ...children)for the elements that usecss. [2]
Run and edit it
It runs in your browser, in a sandboxed frame that cannot see this site; the packages load from esm.sh only after you press Run.
import { jsx, css } from "@emotion/react";
// The css prop is read by Emotion's jsx(). This editor compiles JSX with React's own
// runtime, so elements that use css are created with jsx(type, props, ...children).
const grid = css`
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
width: min(520px, 92vw);
@media (max-width: 520px) { grid-template-columns: 1fr 1fr; }
@media (max-width: 360px) { grid-template-columns: 1fr; }
`;
const cell = css`
background: #1c1f26;
color: #e8eaf0;
border-radius: 12px;
padding: 22px 0;
text-align: center;
font-size: 20px;
font-weight: 600;
@media (max-width: 520px) { background: #2b2140; }
`;
const label = css`
color: hotpink;
font-size: 15px;
margin-bottom: 12px;
&::after { content: "Wide: 3 columns (over 520px)"; }
@media (max-width: 520px) { &::after { content: "Medium: 2 columns (361-520px)"; } }
@media (max-width: 360px) { &::after { content: "Narrow: 1 column (360px or less)"; } }
`;
export default function App() {
return (
<div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: "#111", fontFamily: "system-ui, sans-serif" }}>
<div>
{jsx("div", { css: label })}
{jsx("div", { css: grid },
[1, 2, 3, 4, 5, 6].map((n) => jsx("div", { key: n, css: cell }, n)),
)}
</div>
</div>
);
}
In this frame you see 3 columns; change 520px to 800px in all three styles and run it to see the 2-column layout. Code written by AgentGid [1].
In this frame you see 3 columns; change 520px to 800px in all three styles and run it to see the 2-column layout. Code written by AgentGid [1].Checked Oct 12, 2026: it starts without errors in Chromium with @emotion/react 11.14.0, react 19.3.0, react-dom 19.3.0, @emotion/styled 11.14.1. Needs WebGL.
More Emotion examples
Styled components with Emotion The css prop in Emotion Object styles in Emotion Nested selectors in Emotion
Sources
Explanations written by AgentGid from the official docs; the numbers in brackets point here. The code marked "written by AgentGid" is ours and free to copy.