CONCEPTS
Composition laws
The four laws a style array obeys, and how two of them make the merge a monoid, a category with one object.
A classStyle array merges its styles property by property. Written as an
operation, where merges the style on its right into the one on its left,
that merge obeys four laws. Each one is something you can rely on when you
restructure styles.
Associativity
Grouping does not change the result. Arrays can be nested, so these are the same:
<div classStyle={[[styles.a, styles.b], styles.c]} />
<div classStyle={[styles.a, [styles.b, styles.c]]} />That is what lets you pull part of an array into a variable, or a prop, and put it back anywhere in the same position.
Identity
false, null and undefined merge into nothing, so each of them is the
identity . That is why a condition can sit in the array:
<div classStyle={[styles.base, isActive && styles.active]} />When isActive is false, the array is styles.base alone.
Idempotency
Merging a style with itself changes nothing, so a style that reaches an element twice, through a shared base and a prop, say, does no harm.
No commutativity
Order is the one thing that does matter. When two styles set the same property, the one on the right wins, so swapping them swaps the winner. Styles that set different properties never compete, and their order makes no difference.
A shorthand against its longhand is the exception: the longhand wins in either order. See Specificity.
What the laws add up to
Together, associativity and identity make the merge a monoid: any array, however it is nested or wherever its conditions fall, reduces to one style. The compiler does that reduction at build time, so the element receives a single class list:
Here classA and the rest are not each style's classes laid side by side. The
reduction is a merge, so a property overridden from the right leaves no class
behind:
const styles = css.create({
a: { color: 'red', padding: 4 },
b: { color: 'blue' },
});
<div classStyle={[styles.a, styles.b]} />The element receives two classes, padding: 4px and color: blue; the class
for color: red is not among them. Two classes for the same property never
reach one element, so the cascade is never left to pick the winner.