Best practices
Spacing in .gui: use gap, not an empty row
The single most common habit agents bring over from HTML/CSS — and the one-attribute fix.
A pattern shows up constantly in AI-generated .gui files: an empty element sitting between two real ones, existing only to create visual space.
Don’t
<col> <text>Balance</text> <col height="16"/> <!-- fake spacer --> <text>$4,204.10</text> </col>
It renders correctly, and it will pass a naive visual check against a reference design. It is still wrong, for two concrete reasons: it’s dead markup with no semantic purpose (a node that exists purely as a workaround), and it’s brittle — change the parent’s padding or add a third child and the spacing math has to be redone by hand at every spacer.
The fix: gap
row, col, and grid all take a gap attribute — the space between every child, declared once on the parent.
Do
<col gap="16"> <text>Balance</text> <text>$4,204.10</text> </col>
One number, on the container that actually owns the spacing decision. Add a third child and the gap still applies correctly with no extra markup. This isn’t a style preference — it’s the difference between a value the file can be reasoned about and a value that has to be reverse-engineered from node heights.
Why agents default to the old pattern
It’s inherited from HTML, where a real gap property only reliably exists in flex/grid layout contexts and plenty of training data still comes from table-layout-era markup or naive absolute positioning, where an invisible spacer was the only tool available. .gui’s layout elements always support gap — there’s never a context where the workaround is actually necessary, so an agent that reaches for it either hasn’t been told the format has gap, or is pattern-matching from HTML habit. gui setup installs a skill that teaches this explicitly (see Prompting your agent).
It also affects your score
A dead spacer node is exactly what the Clean level of CCAC scoring flags — unused markup with no layout purpose. Swapping it for gap is a direct, mechanical fix, not a matter of taste.
Frequently asked
Which elements support the gap attribute?
row, col, and grid — every .gui layout container that arranges children in a direction or track system takes a literal gap attribute for the space between them.
Is an empty spacer element ever necessary in .gui?
No. row, col, and grid always support gap, so there’s no layout situation in .gui that requires a dead spacer node the way older HTML table-layout patterns sometimes did.
Does a fake spacer row break validation?
No, it still validates and renders correctly — which is exactly why it’s easy to miss. It does cost points on the Clean level of CCAC scoring as unused markup.