Layout Grid

The Grid and Cell components can be used to create consistent & responsive layouts across your Base Web application. Within a Grid container, Cells can be placed and aligned along a series of columns via the span and skip props.

The implementation uses flexbox which makes it easy to control vertical alignment (align) and cell ordering (order). Almost all of the props available on Cell and Grid are responsive, meaning they accept an array of values that map to various breakpoints defined in your app's theme.

Here are the default responsive values for the grid, based on the default Base Web theme breakpoints:

BreakpointRangeColumnsGutterMargin
Default0 to 319px1-16px
Small320px to 599px416px16px
Medium600px to 1135px836px36px
Large1136px and up1236px64px

All of these values are customizable via your theme. The grid will default to whatever values are in your theme but you can additionally override any of them with props on Grid and Cell.

Examples

Some examples may require you to open them in CodeSandbox to achieve a wide enough viewport for certain behaviors.

Basic

1
2
3
4
5
6
7
8
9
10
11
12

Place cells in a grid container and each cell will align to a column.

Cells are meant to contain your content. The grid implementation calculates margins and paddings for the various containing elements such that any content inside of a cell is properly aligned to a column.

Any cells that do not fit on a single row will wrap to a new row. The default gap between wrapped cell rows is 0. You can specify a gap with the responsive gridGaps prop. You can also use a new Grid below the first one if you want to closely control vertical spacing.

You can nest grids inside of cells or other elements. The cell widths are calculated as percentages of the parent container. Use caution with this pattern though- the main use case for the grid is to align sections of the page using a consistent layout. Nesting can be an indication of a layout that is too complex and requires some design refactoring.

Span

1
2
3
4

Use the span prop to specify how many grid columns a cell should span.

If the number passed to span exceeds the current number of grid columns (based on current breakpoint), the cell will simply shrink to fit the current number of columns. For instance, a cell with a span of 12 will span 8 on a medium viewport, and 4 on a small viewport.

In the example above, each cell has a span of 2. This causes the excess cells to wrap on our small breakpoint. Cells that wrap to a new line will still align content to the columns of the grid.

Sometimes this wrapping behavior is desireable, but sometimes you want to adapt to different breakpoints by setting spans specific to each breakpoint. The layout grid handles this by exposing "responsive" props.

Responsive

1
2
3
4

span is a "responsive" prop. It accepts both a single value or an array of values. Each value in the array corresponds to each breakpoint in our theme.

When you specify the first value in the array, you are specifying the value for any viewport larger than or equal to the first (small) breakpoint in your theme. The second value applies to viewports greater than or equal to the medium breakpoint, and the third value applies to viewports greater than or equal to the large breakpoint.

In the example above, we specify that on the first breakpoint and up each cell should span 1 column. On the second breakpoint and up, each cell should span 2 columns, and on the third breakpoint and up, each cell should span 3 columns: [1, 2, 3]. Effectively, this keeps each cell to 1/4 of the width of the grid on all breakpoints.

This terse way of describing responsive values was originally used in our Block component- it allows you to very quickly specify even the most complicated responsive layouts.

Note, you can omit larger breakpoint values if they do not change. For example, [1, 2] is the same as [1, 2, 2]. This is a result of using a min-height based media query approach in the implementation of the layout grid.

Also note that every Cell prop is "responsive". Almost all of the props for Grid are also "responsive" props, with the exception of behavior and gridMaxWidth, which only accept one value across all breakpoints.

Last thing to note: The grid has only one column on viewports smaller than the first breakpoint (<320px). Cells will effectively take up the full width of the grid. Most props have no reasonable effect with one column so "responsive" props essentially ignore this range.

Hide

1
2
3
4

In this example we hide the first (1) cell on viewports larger than the first breakpoint. Notice how we hide the cell by passing a 0 to span. This is useful for responsive layouts where some section may be hidden on a specific breakpoint.

Skip

1
2

Another common layout scenario is "offsetting" or "skipping" columns. In this example we use the skip prop to offset the 2 cell by 1 column on small, 4 columns on medium, and 7 columns on large viewports. This effectively maximizes the space between the 1 and 2 cells on each breakpoint.

An important detail: skip specifies how many columns the left margin of the cell should span. This means that skip can wrap cells onto a new line in order to allow enough space for that margin. This leads to one other behavior that you may not expect...

Shrink

1

Notice how the cell has a span set to fill each breakpoint, but the skip of 1 takes precedence and shrinks the cell to fit on one line.

Align

1
2
3

You can horizontally align the cells of the grid with the align prop. Note that you can pass align to the entire grid or to an individual cell (or both).

Order

1
2
3

Notice that the 1 cell is rendered last even though it is declared first in our markup.

This prop is mostly useful when used as a responsive prop. Imagine a card that is rendered at the top of a list of items on small viewports, but last on larger viewports, when the items are on a single row.

The order prop is simply a proxy for the CSS property of the same name. Click here to read more about how order works with flexbox.

Behavior

1

To appreciate this example you may need to open it in CodeSandbox. The "behavior" (😅) is only visible on a wider viewport.

The grid can have one of two possible behaviors: fixed or fluid. By default the grid is fixed- that is, once it reaches its maximum width, it will stay centered in the containing element.

A fluid grid essentially ignores any maximum width. The grid will continue to expand to fill the containing element's width ad inifinitum. Note, both fluid and fixed grids still have a margin on both sides.

The behavior prop is not responsive. This is because, below the maximum width, both fluid and fixed grids are identical.

Custom

1
2
3
4
5
6
7
8
9
10
11
12

In this example we customize the grid to have 12 columns at each breakpoint. We also shrink the gutters and margins, add a row gap for wrapped cells, and increase the maximum width of the grid to 1440px.

You can customize pretty much any part of the grid while maintaining the core responsibility of aligning cells to columns. Here are the relevant props (also used in the above example) for customizing the grid:

  • gridColumns
  • gridGaps
  • gridGutters
  • gridMargins
  • gridMaxWidth (Not responsive)

The grid will use whatever values are on your theme grid property as the default values for these props. This way you do not have to create a "wrapper" grid if yours differs from the default Base grid. Click here for the full theme shapeor see below for the grid relevant section of the theme:

const theme = {
grid: {
columns: [4, 8, 12],
gutters: [16, 36, 36],
margins: [16, 36, 64],
gaps: 0,
maxWidth: 1280,
},
};

Note how these are defined in a similar fashion to responsive props. Each value in the array corresponds to a theme breakpoint.

If you want to customize the breakpoints of the grid, you can do so via the breakpoints and mediaQuery properties. The grid will always pull breakpoints from the theme and correlate responsive props with those breakpoints.

API

Grid and Cell