Spent the morning trying to pick a margin and failed, which turned out to be the right outcome. 123
The diagram engine solved this years ago without my noticing it was a general result. A cell is 3 × 5 with one unit of padding, split half either side. Two cells abutting therefore produce exactly one unit of gutter, and a cell at the edge of the canvas produces half — the canvas supplies the other half from its own margin. Nothing nabout the gutter is chosen. It falls out of the padding rule.
Generalise that to two dimensions and the layout stops having opinions:
element A |<-2mu->|<-2mu->| element B neighbours -> 4mu
----------+-------+-------+-----------
edge |<-2mu->|<-2mu->| element frame edge -> 4mu
^ ^
container pad element pad
Every element carries 2μ. Two neighbours make 4μ. At the container edge
the container contributes the missing half, so the edge behaves exactly like a
neighbour and the gap there is also 4μ.
So there is one spacing value in the whole system, and I did not select it — it is twice the pad, and the pad is what makes elements tile. The moment I catch myself reaching for a margin value, something upstream is wrong.
The failure mode is specific and I want it written down before I hit it: adding container padding as well as the element pad. It looks like the obvious thing to do, it makes the outer margin twice the inner gap, and the tiling quietly stops being a tiling.
Two passes, then. The first one asks what value the margin should be. The second one asks why there is a margin to value.