Styling
Studio writes this format for you. The Design inspector and Project Styles produce everything below. This page documents the style model for hand-editing and reference.
Styles are JSON objects. Property names are the CSS ones in camelCase, the same spelling the CSSOM uses, so
background-color
is written
backgroundColor
.
Inline styles
The
style
property accepts a JSON object:
{
"tagName": "div",
"style": {
"backgroundColor": "blue",
"marginTop": "10px",
"fontSize": "16px",
"display": "flex"
}
}
Nested CSS selectors
Keys beginning with
:
,
.
,
&
, or
[
are treated as nested selectors:
{
"style": {
"backgroundColor": "blue",
":hover": {
"backgroundColor": "darkblue",
"cursor": "pointer"
},
".child": { "color": "white" },
"&.active": { "outline": "2px solid white" }
}
}
Inline properties apply directly to the element. Nested rules are emitted as a scoped
<style>
block keyed on a
generated class
,
.<tagName>-<n>
, which the build also puts on the element:
<div class="sty-card-0">…</div>
.sty-card-0:hover {
padding: 8px;
}
(You'll also see
data-jx-static
and
data-jx-prerendered
in compiled output. Those mark hydration state and are never used as CSS selectors.)
Named media breakpoints
Declare breakpoints at root level with
$media
:
{
"$media": {
"--sm": "(min-width: 640px)",
"--md": "(min-width: 768px)",
"--lg": "(min-width: 1024px)",
"--dark": "(prefers-color-scheme: dark)"
}
}
Use
@--name
keys in any style object:
{
"style": {
"fontSize": "14px",
"@--md": { "fontSize": "16px" },
"@--dark": { "color": "#ccc" },
"@(min-width: 1280px)": { "fontSize": "18px" }
}
}
@--name
references named breakpoints.
@(condition)
is a literal inline media query, and the
parentheses are the query's own: a feature query keeps them (
@(min-width: 1280px)
), while a
bare media type does not, so
@(print)
emits
@media print
.
Color-scheme variants
A
$media
entry whose value is exactly a
prefers-color-scheme
query (like
--dark
above) is a
scheme query
: its
@--dark
blocks respond both to the OS preference and to a visitor-forced scheme, and the compiler wires up
color-scheme
and no-flash persistence automatically. See
Color schemes
for the full contract and how to build a switcher.
Static style extraction
The compiler extracts every static
style
definition into a single
<style>
block in the document
<head>
, so a page carries one stylesheet rather than a rule per element.
Design tokens as CSS custom properties
Define tokens in your
project.json
style
block and use them everywhere:
{
"style": {
":root": {
"--color-primary": "#3b82f6",
"--color-surface": "#ffffff",
"--font-sans": "Inter, system-ui, sans-serif"
}
}
}
Components reference tokens with standard
var()
:
{
"style": {
"color": "var(--color-primary)",
"fontFamily": "var(--font-sans)"
}
}
CSS custom properties cascade through the DOM, so every component can use them without importing anything.