Styling
Selectors, resolution order, and inline overrides.
The business card from chapter 1 is functional but bland. This chapter adds visual polish using Joy DOM's three selector types and explains how rules compose when several apply to the same node.
The three selectors
| Selector | Example | Matches |
|---|---|---|
| Type | p | Nodes with type: "p". |
| Class | .title | Nodes whose className array includes title. |
| Id | #hero | Nodes with id: "hero". |
Use type selectors for global defaults (every paragraph, every heading), classes for reusable patterns (.card, .row), and ids for one-off targeting (#hero, #footer).
Polish the card
Add a border, accent the headline color, and align the meta text:
{
"version": 1,
"style": {
".card": {
"display": "flex",
"flexDirection": "column",
"gap": {
"value": 4,
"unit": "px"
},
"padding": {
"value": 24,
"unit": "px"
},
"backgroundColor": "#ffffff",
"borderWidth": {
"value": 1,
"unit": "px"
},
"borderStyle": "solid",
"borderColor": "#e2e8f0",
"borderRadius": {
"value": 12,
"unit": "px"
}
},
"h1": {
"display": "flex",
"fontSize": {
"value": 28,
"unit": "px"
},
"color": "#0f172a",
"fontWeight": "bold"
},
"p": {
"display": "flex",
"fontSize": {
"value": 14,
"unit": "px"
},
"color": "#475569"
},
".meta": {
"display": "flex",
"textTransform": "uppercase",
"letterSpacing": {
"value": 1,
"unit": "px"
}
}
},
"breakpoints": [],
"layout": {
"type": "div",
"props": {
"className": ["card"]
},
"children": [
{
"type": "h1",
"children": ["Avery Chen"]
},
{
"type": "p",
"props": {
"className": ["meta"]
},
"children": ["Product designer · Tokyo"]
}
]
}
}Two things are worth noticing:
pand.metaboth apply to the meta paragraph. Class selectors run after type selectors, so.metaoverrides any conflicting property without needing inline styles.- The
h1rule sets only the typography for the heading; the parent.cardalready drives layout.
Resolution order
When multiple rules touch the same node, Joy DOM applies them in this order, with later sources overriding earlier ones:
- Type selector.
- Class selectors, in the order listed in
className. - Id selector.
- Breakpoint styles when a matching breakpoint activates.
- Inline
props.style.
So className: ["meta", "highlight"] applies .meta first, then .highlight - the later class wins on shared properties.
Inline styles for one-offs
When a node needs a value that should not be reused, set it inline:
{
"type": "p",
"props": {
"className": ["meta"],
"style": {
"display": "flex",
"color": "#16a34a"
}
},
"children": ["Available for new projects"]
}props.style wins over every shared selector. Reach for it sparingly - most styles should live on a class so they're easy to reuse.
Color values
Joy DOM colors are hex strings. rgb() and rgba() are not supported. If you need partial
transparency, use the opacity property - see §5.7.2.
Wrap-up
The card has its visual identity. Next we make it adapt to its container with breakpoints.
Spec references: §4 Styles · §5 Properties