Skip to content

Grid

When to use it

The Grid object (see About Components for the semantic difference between Objects and Components) is used to create a flexible and responsive layout for your components. It allows you to define columns that adjust based on the screen size (not container width), providing a consistent and organized structure.

TIP

If column widths are not so important but alignment is, take a look at Flex as well.

Variants

  • Auto: Use the .o-grid--auto modifier to make the whole grid fluid, with consistent column widths, allowing columns to wrap as needed without specifying column classes. Auto grids aim for --cols: 4 columns by default, but the actual number of columns remains flexible. The calculated minimum item width is clamped between --grid-min-item-size-min (14rem) and --grid-min-item-size-max (18rem) by default.
  • Gap None: Use the .o-grid--bleed, or the utility .u-gap--none to reset all column gaps.
  • Gap Sizes: Use the utilities .u-gap--[xs|s|m|l|xl|xxl] to add extra gutter space between columns.
  • Column Widths: Use the .o-grid__col-[xs|sm|md|lg|xl]-N classes to define column widths for different screen sizes, where N is a number from 1 to 12. Note: These variants does not work in auto grids.
  • Alignments: Use .o-grid--align-[start|center|end|space-between] and similar to align child elements along the cross axis. Dito classes for the main axis is .o-grid--justify-[…].
  • Self alignments: Use .o-grid--align-self-[start|center|end|space-between] and similar to align the grid element itself along the cross axis. Dito classes for the main axis is .o-grid--justify-self-[…].
  • Order: Use .o-grid--order-N-[xs|sm|md|lg|xl] to change the visual order on screens matching the [xs|sm|md|lg|xl] modifiers, where N is a sort order number from 0 to 3 (0 being the default).

Auto grid sizing

.o-grid--auto is useful when every child should have the same fluid width and wrap naturally as the available space changes. It does not use the fixed 12-column child classes.

The --cols value is an ideal column count, not a hard column count. The grid uses it to calculate a preferred minimum item width:

css
calc((100% - calc(var(--cols) - 1) * var(--gap, var(--space-m))) / var(--cols))

That preferred width is then clamped between --grid-min-item-size-min and --grid-min-item-size-max. With the default values, the grid says: "try to make four columns, but keep each item's minimum width between 14rem and 18rem."

Use these variables depending on the layout goal:

  • --cols: Change the ideal number of columns. Lower values make items wider and wrap earlier; higher values make items narrower and allow more columns when there is room.
  • --grid-min-item-size-min: Set the smallest acceptable item width before the grid wraps to fewer columns.
  • --grid-min-item-size-max: Set the largest preferred minimum item width before items simply grow through 1fr.

The grid stores the calculated value in --grid-min-item-size internally. Product code should normally change --cols, --grid-min-item-size-min, or --grid-min-item-size-max instead of replacing that calculation.

Centering a narrower column

o-grid--justify-center affects alignment, but since o-grid uses a full-width 12-column template, it does not move the columns themselves. To horizontally center a narrower column on its row, add o-grid--justify-self-center to the column.

Main vs Cross axis

In CSS Flexbox, the main axis is the primary axis along which flex items are laid out. It is defined by the flex-direction property. The cross axis is perpendicular to the main axis and is used for alignment and spacing in the perpendicular direction. For example, if flex-direction is set to row, the main axis is horizontal, and the cross axis is vertical.

What it looks like

Code examples

html
<div class="o-grid o-grid--auto">
    <div class="c-box c-box--info">
        Cell 1
    </div>
    <div class="c-box c-box--info">
        Cell 2
    </div>
</div>
<div class="o-grid o-grid--auto o-grid--gap-none">
    <div class="c-box c-box--info">
        Cell 1
    </div>
    <div class="c-box c-box--info">
        Cell 2
    </div>
    <div class="c-box c-box--info">
        Cell 3
    </div>
</div>
<div class="o-grid o-grid--auto u-gap--xl">
    <div class="c-box c-box--info">
        XL gap 1
    </div>
    <div class="c-box c-box--info">
        XL gap 2
    </div>
    <div class="c-box c-box--info">
        XL gap 3
    </div>
    <div class="c-box c-box--info">
        XL gap 4
    </div>
    <div class="c-box c-box--info">
        XL gap 5
    </div>
    <div class="c-box c-box--info">
        XL gap 6
    </div>
</div>
html
<div class="o-grid o-grid--auto" style="--cols: 6; --grid-min-item-size-min: 8rem; --grid-min-item-size-max: 12rem">
    <div class="c-box c-box--info">
        Cell 1
    </div>
    <div class="c-box c-box--info">
        Cell 2
    </div>
    <div class="c-box c-box--info">
        Cell 3
    </div>
    <div class="c-box c-box--info">
        Cell 4
    </div>
    <div class="c-box c-box--info">
        Cell 5
    </div>
    <div class="c-box c-box--info">
        Cell 6
    </div>
</div>
html
<div class="o-grid">
    <div class="o-grid__col-4">
        <div class="c-box c-box--info">
            Cell 1
        </div>
    </div>
    <div class="o-grid__col-8">
        <div class="c-box c-box--info">
            Cell 2
        </div>
    </div>
    <div class="o-grid__col-12">
        <div class="c-box c-box--info">
            Cell 3
        </div>
    </div>
</div>
html
<div class="o-grid">
    <div class="o-grid__col-12 o-grid__col-xs-8 o-grid--justify-self-center">
        <div class="c-box c-box--info">
            Centered column (responsive)
        </div>
    </div>
    <div class="o-grid__col-12">
        <div class="c-box c-box--info">
            Next row
        </div>
    </div>
</div>

Accessibility notes

Although this component support visual reordering of content (using o-grid--order- attributes), please try to match the visual order of elements with the DOM order. Screen readers and keyboard navigation typically follow the DOM order, so placing elements in a logical sequence can be crucial for users relying on assistive technologies.

However, the order of content in a sequence is not always meaningful – providing a particular linear order is only required where it affects meaning. There may even be more than one order that is "correct" (according to the WCAG 2.0 definition).