Grid
WxRow and WxCol are the 24-column grid a screen is laid out on: a form in two columns, a row of statistic cards, a filter bar that becomes a stack on a phone.
For the shell around the screen, see Layout; for a single row or stack of controls, Space is less machinery.
Usage
<template>
<wx-row :gutter="16">
<wx-col :span="12">Left half</wx-col>
<wx-col :span="12">Right half</wx-col>
</wx-row>
</template>span counts columns out of 24, so twelve is a half, eight a third, six a quarter.
Gutters
gutter is the gap between columns, in pixels or as any CSS length. Left alone it is --wx-gap, the step the surrounding layout spaces everything else by — 16 where nothing sets one. Once the columns wrap, the gap between lines is the same — unless gutter-y says otherwise:
<template>
<wx-row :gutter="24" :gutter-y="12">…</wx-row>
</template>The gutter is half a gutter of padding on each column, pulled back by a negative margin on the row, rather than a column-gap. That is what keeps span="12" an honest half: a gap subtracted from the track would leave two halves wider than the line they sit on.
Responsive
span is the base and holds at every width. sm, md, lg and xl override it from 640, 768, 1024 and 1280px up — narrowest first, so a column that takes the whole line when there is little room and a quarter of it when there is plenty reads in that order:
<template>
<wx-col :span="24" :md="12" :lg="6">…</wx-col>
</template>Each breakpoint also takes an offset of its own:
<template>
<wx-col :span="24" :lg="{ span: 16, offset: 4 }">…</wx-col>
</template>The breakpoints measure the row, not the window
They are container queries: md means "from 768px of row", not "from 768px of viewport". The same grid therefore stacks inside a 400px drawer and spreads across a wide screen without knowing which it is in, and a main column that just lost 240px to a sidebar reflows the moment it narrows rather than when the window does. On a page whose content runs the full width the two readings agree, which is why the numbers are the familiar ones.
The container is named, so a WxCol used outside a WxRow does not start answering to the nearest card: with no row above it, a column keeps its base span at every width.
Support is Chrome 105, Safari 16 and Firefox 110 and up — anything older shows the base span, which for the usual mobile-first span="24" is a stack, not a broken layout.
Arranging the row
<template>
<wx-row justify="between" align="center" :wrap="false">…</wx-row>
</template>order moves a column without moving it in the markup — the summary panel that belongs first on a phone and last on a desktop:
<template>
<wx-row>
<wx-col :span="24" :lg="16" :order="2">The form</wx-col>
<wx-col :span="24" :lg="8" :order="1">The summary</wx-col>
</wx-row>
</template>Row
| Prop | Type | Default | Description |
|---|---|---|---|
gutter | number | string | step | Gap between columns |
gutterY | number | string | gutter | Gap between wrapped lines |
justify | 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly' | — | Distribution along the row |
align | 'start' | 'center' | 'end' | 'stretch' | 'baseline' | — | Alignment across it |
wrap | boolean | true | Lets columns wrap |
as | string | Component | 'div' | The element to render |
Col
| Prop | Type | Default | Description |
|---|---|---|---|
span | number | 24 | Columns out of 24, at every width |
offset | number | — | Empty columns before the cell |
sm | number | { span?: number; offset?: number } | — | From 640px of row up |
md | number | { span?: number; offset?: number } | — | From 768px of row up |
lg | number | { span?: number; offset?: number } | — | From 1024px of row up |
xl | number | { span?: number; offset?: number } | — | From 1280px of row up |
order | number | — | Visual order within the row |
as | string | Component | 'div' | The element to render |
Both take a default slot and nothing else.
How the breakpoints work
Every width a column is given is written out as a CSS variable — --wx-col-span, --wx-col-span-md and so on — and the stylesheet holds one @container rule per breakpoint, each falling back to the one below it. Nothing is generated per span, so the grid costs four rules rather than the several hundred a class-per-span grid ships, and a column can be adjusted from the outside:
<template>
<wx-col style="--wx-col-span: 10">Ten columns, set by hand</wx-col>
</template>