Breakpoints
Responsive overrides with media-query-like conditions.
A document that looks right at one width often falls apart at another. Joy DOM breakpoints apply overrides when media-query-like conditions match - and unlike CSS, the conditions live in JSON next to the rest of the document.
This chapter adds two breakpoints to the business card from chapter 2: one that tightens the layout on narrow screens, and one that swaps colors for print.
How a breakpoint is shaped
Every breakpoint has three required fields:
| Field | Description |
|---|---|
conditions | Array of conditions that activate the override. |
nodes | Per-node prop overrides keyed by node id. |
style | Shared style overrides keyed by selector. |
Both nodes and style can be empty objects - only the field whose changes you want needs entries.
Narrow-screen tightening
When the viewport is under 480 px, shrink the padding and stack the typography tighter:
{
"conditions": [
{
"type": "feature",
"name": "width",
"operator": "<",
"value": 480,
"unit": "px"
}
],
"nodes": {},
"style": {
".card": {
"display": "flex",
"padding": {
"value": 16,
"unit": "px"
}
},
"h1": {
"display": "flex",
"fontSize": {
"value": 22,
"unit": "px"
}
}
}
}A few things to note:
- The condition uses
operator: "<"to mean "viewport width is below 480 px." Supported operators are<,<=,>,>=. - Each overridden selector replays the
displayvalue. Breakpoint style entries are independent partial styles - they don't merge into prior rules, they sit beside them and apply later. nodes: {}is required even when you don't override any node props.
Print swap
Show the meta line in black and remove the card border for print:
{
"conditions": [
{
"type": "type",
"value": "print"
}
],
"nodes": {},
"style": {
".card": {
"display": "flex",
"borderWidth": {
"value": 0,
"unit": "px"
},
"borderColor": "#ffffff"
},
".meta": {
"display": "flex",
"color": "#000000"
}
}
}{ "type": "type", "value": "print" } corresponds to @media print in CSS.
Combine conditions
and, or, and not let you express richer conditions:
{
"op": "and",
"conditions": [
{
"type": "feature",
"name": "width",
"operator": ">=",
"value": 768,
"unit": "px"
},
{
"type": "feature",
"name": "orientation",
"value": "landscape"
}
]
}For exclusions:
{
"op": "not",
"condition": {
"type": "type",
"value": "print"
}
}When two breakpoints match
If more than one breakpoint matches a viewport, Joy DOM picks exactly one:
- The breakpoint with the more specific condition set wins.
- If specificity is tied, the later breakpoint in the array wins.
Joy DOM does not merge multiple matches. Order your breakpoints from least to most specific to make this predictable.
Toggling visibility
Use display: "none" inside a breakpoint to hide a node. Removing the entry brings it back. See
§6.4 Common patterns.
Put it together
Drop both breakpoints into the document's breakpoints array - order matters, so put the narrower-condition one later:
{
"version": 1,
"style": {
"...": "..."
},
"breakpoints": [
{
"conditions": [
{
"type": "type",
"value": "print"
}
],
"nodes": {},
"style": {
"...": "..."
}
},
{
"conditions": [
{
"type": "feature",
"name": "width",
"operator": "<",
"value": 480,
"unit": "px"
}
],
"nodes": {},
"style": {
"...": "..."
}
}
],
"layout": {
"...": "..."
}
}Resize the viewport in your browser to see the narrow-screen rule kick in. Use your browser's print preview to see the print rule.
Wrap-up
The card is responsive. Next we'll add a custom component - something Joy DOM does not render natively - and make it part of the document. See chapter 4.
Spec references: §6 Breakpoints