Skip to content

CdsGrid

A responsive modular grid: CdsGrid, CdsRow and CdsCol lay the content out in columns — from 4 on a phone to 16 on wide screens. The grid works in two modes — Flexbox (the default) and CSS Grid — and the whole markup is also available as ready-made CSS classes, without a single component.

Storybook GitLab
Test coverage: 100% — good coverage
API in specs
18 / 18 props, events, slots and exposed members with a test
Test cases
29 unit · 0 browser
Known bugs
1 pinned by an it.fails test
Code coverage
100% lines · 94.9% branches measured in v4.0.0-alpha.13
A11y (axe)
1 recommendations in 16 stories measured in v4.0.0-alpha.11

The grid lays out the content inside a page. Build the frame of the application — the header, the drawers and the footer — from CdsLayout.

Anatomy ​

Every layout starts with CdsGrid — the container can sit at any nesting level as long as it takes the full width of its parent. Inside a Flexbox grid the CdsCol columns are grouped into CdsRow rows; in CSS Grid mode the rows are not needed — the columns wrap on their own.

Variations ​

Flexbox or CSS Grid ​

By default the grid is built on Flexbox. The second mode — CSS Grid — is turned on once for the whole application by the cssGrid option and adds capabilities Flexbox does not have: nested subgrid grids and explicit positioning of the columns through span, start and end. In exchange, the Flexbox mode can change the order of the columns through order.

ts
import { createCds } from '@central-design-system/components';

const cds = createCds({ cssGrid: true });

The components and the props are the same in both modes, only the generated markup differs. In the examples below the CSS Grid mode is turned on locally — through provide(CssGridSymbol, true); in an application the cssGrid option is enough.

Columns and breakpoints ​

The width of a column is set by the xs–xl breakpoint props: the number says how many grid columns CdsCol takes starting from that breakpoint. The values work "bottom-up": md="4" applies to md and wider.

The number of columns in the grid depends on the width of the screen, so the same number takes a different share of the row on different breakpoints:

BreakpointScreen widthColumns in the grid
xs≥ 320px4
sm≥ 672px8
md≥ 1056px16
lg≥ 1312px16
xl≥ 1584px16

Combine the breakpoints to describe the behavior of the layout on every screen: here each column takes half of the row on a phone and a quarter starting from a tablet. The value 0 hides the column on a breakpoint.

Automatic columns ​

A CdsCol without breakpoint props splits the row evenly with its neighbors: one column takes the whole width, four take a quarter each. Handy when the shares are equal and there is no point in recalculating them per breakpoint. Works in Flexbox mode only.

Grid modes ​

The narrow and condensed props shrink the gap between the columns from 32px to 16px and 1px respectively. CdsRow has the same props — that is how the modes are mixed inside one grid. The wide prop removes the maximum width limit (1584px) and stretches the grid across the whole container.

Offset and order ​

Instead of a number, a breakpoint prop can take an object. The span key sets the width, offset shifts the column to the right by the given number of columns.

The order key changes the visual order of the columns without touching the markup — to show the columns on a desktop in a different sequence than in the DOM, for example. Works in Flexbox mode only.

CSS Grid mode ​

In CSS Grid mode the columns go straight into CdsGrid — without CdsRow: the grid wraps them onto a new line itself when the row is full.

A nested grid with the subgrid prop inherits the columns of its parent: put it inside a CdsCol and its columns line up exactly with the lines of the outer grid. The narrow and condensed modes of a nested grid work independently from the root one.

A column can be positioned explicitly: in a breakpoint object start and end set the starting and the ending grid line, and the span prop fixes the range for all breakpoints at once — as a number or as a share: '25%', '50%', '75%', '100%'.

CSS classes ​

The whole grid is duplicated with utility classes — lay a layout out without Vue components: in emails, on static pages or inside somebody else's code. The components generate the same classes, so both ways mix freely.

Classes of the Flexbox grid:

ClassPurpose
cds-gridGrid container
cds-grid-narrow / cds-grid-condensedNarrow (16px) and condensed (1px) gap
cds-grid--wideNo maximum width limit
cds-rowRow; cds-row-narrow, cds-row-condensed — modes
cds-col-{bp}-{n}Column n wide on the bp breakpoint and wider
cds-col-{bp} / cds-col-{bp}-autoAutomatic column / width by content
cds-offset-{bp}-{n}Shift to the right by n columns
cds-order-{bp}-{n}Visual order of the column
cds-row-padding / cds-col-paddingVertical paddings equal to half of the gutter
cds-aspect-ratio cds-aspect-ratio--{w}x{h}Aspect ratio of a block: 16x9, 4x3, 1x1, …

Classes of the CSS Grid mode:

ClassPurpose
cds--css-gridContainer; --narrow, --condensed, --wide
cds--css-grid-columnColumn
cds--col-span-{n}Range of n columns on all breakpoints
cds--{bp}:col-span-{n}Range starting from the bp breakpoint
cds--col-span-{25|50|75|100}Range as a share of the grid
cds--col-start-{n} / cds--col-end-{n}Starting and ending line
cds--subgridNested grid; modes — --narrow and so on

The cds-no-gutter and cds-no-gutter--start / cds-no-gutter--end classes remove the paddings of the columns — for the whole row or on one side. Their counterparts cds-hang--start / cds-hang--end give the padding back to the content when it has to be aligned to the modular grid.

Guidelines ​

Scenarios ​

Card tiles ​

A showcase of reports: on a phone the cards go in a column, on a tablet two per row, on a wide screen four in a row. The cds-row-padding class gives the vertical gap between the rows of the tiles.

Two-column form ​

The grid lays out the fields of a form: the paired fields (sm="4" md="8") split the row in half starting from a tablet, while the comment and the buttons take the whole row. On a phone everything folds into a single column with no extra conditions. The vertical rhythm comes from the py-1 utility classes on the columns — tighter than cds-row-padding — and hide-details on the controls removes the reserved area for messages.

List with filters ​

The classic "filters on the left, results on the right" proportion: the panel takes 4 columns, the list takes 12. On a phone and a tablet the filters stand above the list — that is what the full-width xs and sm values are for.

API ​

CdsGrid ​

Props

NameTypeDefaultDescription
condensedboolean | undefined—Condensed grid. The gap is reduced to 1px on both sides
narrowboolean | undefined—Narrow grid
subgridboolean | undefined—Only CSS Grid supported. A nested grid
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
wideboolean | undefined—Removes the default max-width and stretches the grid across the whole width of the container

Slots

NameTypeDescription
defaultanyRows of the grid — CdsRow

CdsRow ​

Props

NameTypeDefaultDescription
condensedboolean | undefined—Condensed grid. The gap is reduced to 1px on both sides
narrowboolean | undefined—Narrow grid
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render

Slots

NameTypeDescription
defaultanyColumns of the row — CdsCol

CdsCol ​

Props

NameTypeDefaultDescription
lgColumnBreakpoint<ColumnGridBreakpoint | ColumnFlexBreakpoint>—>1312px
mdColumnBreakpoint<ColumnGridBreakpoint | ColumnFlexBreakpoint>—>1056px
smColumnBreakpoint<ColumnGridBreakpoint | ColumnFlexBreakpoint>—>672px
spanstring | number | ColumnSpanType | undefined—Only CSS Grid supported. A permanent column range, start or end values that never change.
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
xlColumnBreakpoint<ColumnGridBreakpoint | ColumnFlexBreakpoint>—>1584px
xsColumnBreakpoint<ColumnGridBreakpoint | ColumnFlexBreakpoint>—>320px

Slots

NameTypeDescription
defaultanyContent of the column