Grid
Lines, squares, dots or plain paper, with independent ink and paper colours. The default pitch is one 20px square. The Grid draws the background; your layout places the content.
Design examples
Section titled “Design examples”The visible grid makes the shared row pitch and icon columns easy to inspect.
<section class="specimen">
<div style="position:relative;isolation:isolate;padding:var(--ds-unit)"><ds-grid contained></ds-grid><div style="position:relative"><ds-row class="line" ><span class="mark"><ds-icon type="page" size="large" aria-hidden="true"></ds-icon></span><ds-text literal >North window</ds-text></ds-row><ds-row class="line" ><span class="mark"><ds-icon type="page" size="large" aria-hidden="true"></ds-icon></span><ds-text literal >East courtyard</ds-text></ds-row><ds-row class="line" ><span class="mark"><ds-icon type="page" size="large" aria-hidden="true"></ds-icon></span><ds-text literal >Reading room</ds-text></ds-row><ds-row class="line" ><span class="mark"><ds-icon type="page" size="large" aria-hidden="true"></ds-icon></span><ds-text literal >West staircase</ds-text></ds-row></div></div>
</section>
<style>
.specimen { width: 100%; min-width: 0; --cell: calc(20px * var(--sf, 1)); }
.specimen .line { width: 100%; }
.specimen .grow { flex: 1; min-width: 0; }
.specimen .muted { color: var(--ds-text-color-muted); }
.specimen .mono { --ds-typeface-regular: var(--ds-typeface-mono); font-variant-numeric: tabular-nums; }
.specimen .value { width: calc(4 * var(--cell)); text-align: right; }
.specimen .mark { display: inline-flex; align-items: flex-end; width: var(--cell); height: var(--ds-control-height); flex: 0 0 var(--cell); }
.specimen .columns { display: flex; flex-wrap: wrap; gap: var(--cell); }
.specimen .columns > * { min-width: 0; }
.specimen fieldset { border: 0; padding: 0; margin: 0; }
.specimen legend { padding: 0; }
.specimen label { display: flex; align-items: flex-end; gap: calc(var(--cell) / 2); min-height: var(--cell); }
.specimen ds-panel { height: calc(10 * var(--cell)); }
</style> Try it
Section titled “Try it”Change the ruling, spacing, ink and paper. The content stays in place.
<div class="grid-controls">
<label>Pattern <ds-select><select data-grid-option="pattern"><option value="grid">Squares</option><option value="lines">Lines</option><option value="columns">Columns</option><option value="dots">Dots</option><option value="none">Plain</option></select></ds-select></label>
<label>Spacing <ds-select><select data-grid-option="size"><option value="10">10px</option><option value="20" selected>20px</option><option value="40">40px</option></select></ds-select></label>
<label>Rows <ds-select><select data-grid-option="row-size"><option value="">Square</option><option value="30">30px</option><option value="40">40px</option></select></ds-select></label>
<label>Ink <ds-select><select data-grid-option="color"><option value="">Neutral</option><option value="var(--ds-sharp-blue)">Blue</option><option value="var(--ds-apple-green)">Green</option><option value="var(--ds-pink)">Pink</option></select></ds-select></label>
<label>Paper <ds-select><select data-grid-option="paper"><option value="">Clear</option><option value="color-mix(in srgb, var(--ds-sharp-blue) 12%, var(--background))">Blue</option><option value="color-mix(in srgb, var(--ds-apple-green) 12%, var(--background))">Green</option><option value="color-mix(in srgb, var(--ds-pink) 12%, var(--background))">Pink</option></select></ds-select></label>
</div>
<div style="position: relative; isolation: isolate; width: 100%; min-height: calc(160px * var(--ds-sf, 1));">
<ds-grid contained></ds-grid>
<div style="position: relative; padding: calc(20px * var(--ds-sf, 1));"><ds-text>Words stay on the paper.</ds-text></div>
</div> const grid = document.querySelector('ds-grid');
document.querySelectorAll('[data-grid-option]').forEach(control => {
control.addEventListener('change', () => {
const attribute = control.dataset.gridOption;
if (control.value) grid.setAttribute(attribute, control.value);
else grid.removeAttribute(attribute);
});
}); Attributes
Section titled “Attributes”| Attribute | Default | What it does |
|---|---|---|
pattern | grid | grid, lines, columns, dots or none. |
size | 20 | Column spacing in unscaled pixels; 10 gives half squares. |
row-size | Same as size | Independent row pitch, such as 30 for taller rows. |
color | Quiet neutral ink | Any CSS colour, including a token such as var(--ds-sharp-blue). |
paper | Transparent | Any CSS colour or colour mix for the paper. |
contained | false | Fill a positioned container instead of overlaying the viewport. |
align | center | left, center or right for the fixed overlay. |
Use a positioned wrapper for contained paper. Keep content in a positioned sibling above the Grid, as in the example. The component ignores pointer events and has no interactive or readable content. Changing the ruling does not move or resize the surrounding content.
Colours can use light-dark() or inherited theme tokens. Removing color or paper restores the theme default. pattern="none" keeps the paper colour while removing its marks.
Scale and alignment
Section titled “Scale and alignment”--ds-sf scales spacing and overlay dimensions; --sf is the fallback for older surfaces. A 20px pitch remains aligned with a fourteen-square phone layout when it shares that layout’s scale. Rules stay one physical CSS pixel by default.
Override --ds-grid-color, --ds-grid-paper, --ds-grid-stroke, --ds-grid-origin-x and --ds-grid-origin-y at the host. --ds-grid-unit and --ds-grid-row accept already-scaled pitches. The fixed overlay accepts --ds-grid-width, --ds-grid-height and --ds-grid-z-index. A contained Grid fills its wrapper and scrolls with it.
Page shortcuts
Section titled “Page shortcuts”On the documentation, press G three times to toggle the separate page inspection grid. Press L three times to inspect the layout: named areas in dashed outlines with their name and size (give them data-ds-area="name"), text and fields in green boxes, and every component outlined with its tag name, such as ds-select. Escape hides the inspection overlays. Typing in a field does not trigger them.