A Direction and a Gap — Layout Without Coordinates

5 min
GoalScreen course, part 2. Placing several things looks like it needs coordinates, but linear takes only a direction and a gap. Why avoiding coordinates is a condition here, not a taste.

Part 1's screen had three nodes, each holding exactly one child. Real screens are not like that.

The node that holds several

{ "type": "linear", "direction": "vertical", "spacing": 12, "alignment": "center",
  "children": [ ... ] }

linear takes children, and decides exactly three things.

  • direction — vertical or horizontal
  • spacing — the gap between them
  • alignment — how they line up on the cross axis

To lay them out sideways, change direction on that node. The children are untouched.

{ "type": "linear", "direction": "horizontal", "spacing": 16,
  "children": [
    { "type": "box", "width": 90, "height": 56, "decoration": { "color": "#ede9fe", "borderRadius": 10 } },
    { "type": "box", "width": 90, "height": 56, "decoration": { "color": "#ddd6fe", "borderRadius": 10 } },
    { "type": "box", "width": 90, "height": 56, "decoration": { "color": "#c4b5fd", "borderRadius": 10 } } ] }

box is a rectangle with a size and a look. Give it a child and it becomes that child's container; leave it empty and it is just a painted surface. These three are empty.

There are no coordinates

Nowhere in this definition is there a top, left, x, or y. That is not laziness in the runtime.

A screen arriving from a server means whoever wrote the screen does not know the size of the space it will land in. This 906-byte file is the same file at 1000 pixels wide, on a tablet, and on a desktop window dragged to half width. Write coordinates and it is correct in exactly one of those.

A direction and a gap can be written without knowing the size. So that is all this layer has.

The check — coordinates fail it

grep -qE '"(top|left|right|bottom|x|y|dx|dy)"' screens/step2.json && \
  die "step2: the layout is positioned by hand"
grep -q '"direction"' screens/step2.json || die "step2: no direction"
grep -q '"spacing"' screens/step2.json || die "step2: no gap"

The first line and the other two point opposite ways: the first fails on presence, the rest on absence.

The check is needed because the render cannot tell the difference. Hand-positioned coordinates produce exactly this picture too — for as long as the window does not change size.

The render

step2  906 B, 12 lines, type "page" -> step2.png

A vertical linear holding two lines of text and one horizontal linear, which holds three boxes of different colours. spacing is 12 in one and 16 in the other, so the two rhythms are visibly different.

How much size to write down

The boxes carry width and height. Not coordinates, but absolute all the same.

That line gets blurry in practice. The rule is one sentence: if a value can only be decided by knowing what is outside, it does not go in the screen definition. A box's size is a property of the box, so it can be written. A box's position depends on its siblings and its parent, so it is left to linear.

Run it yourself

cd content/sample/course-ui
bash verify.sh
open captures/step2.png

Change "direction": "horizontal" to "vertical" in screens/step2.json and run again: the three boxes stack. The host is not touched.

What to take away

  1. linear — direction · spacing · alignment
  2. box — a size and a look, child optional
  3. The no-coordinates check — the render cannot tell, so the definition is read

Next

So far the screen is fixed: only what the file says shows up. Next, how a value that is not in the file gets on the screen.

Run the sample

cd course-ui
bash verify.sh