Vistaprint
styleKeysgrid

Grid

The grid is an invisible framework responsible for the order and rhythm of a page. By imposing constraints on layout, the grid makes it easy to achieve consistent and proportionate designs across devices.

  • The grid is divided into 12 even column widths. The most common layouts divide this space up evenly, e.g. three 4-column, or two 6-columns.

    • On Extra-Small and Small screens (e.g. phones and tablets), you should only divide a row into 3-column, 6-column, 9-column, or 12-column sections.

  • The grid uses fluid widths for the columns, so as the overall grid widens, so will each of its columns.

  • Gutter (between grid elements) and margin (around the whole grid) differ according to screen size, where larger screens have more whitespace.

Playground

Usage

The grid is made up of 3 components:

  • Grid Container - root of the grid. All of its children must be Rows.

  • Row - a single row within a Grid Container. All of its children must be Columns.

  • Column - a column within a Row. Its children can be arbitrary content, or a nested Row!

A Grid Container can have any number of Rows, and a Row can have any number of Columns.

Each Row supports 12 columns of content, divided up evenly, and with a gutter between them.

Each Column element needs to specify how many grid columns it spans, using either the span prop (in React) or a col-* class (in vanilla).

Span 3/12
Span 9/12
Share
Share
jsx
<div class="grid-container">
<div class="row">
<div class="background-light-grey col-3">Span 3/12</div>
<div class="background-light-blue col-9">Span 9/12</div>
</div>
</div>

You can safely place more than 12 columns' worth of content inside a single Row; the Row will show the first 12 columns' worth, and then will line-wrap the rest:

Span 4/12
Span 4/12
Span 4/12
Span 4/12
Share
Share
jsx
jsx
<GridContainer>
<Row>
<Column span={3}>Content inside a 3-column element</Column>
<Column span={9}>Content inside a 9-column element</Column>
</Row>
</GridContainer>
<div class="grid-container">
<div class="row">
<div class="col-3">Content inside a 3-column element</div>
<div class="col-9">Content inside a 9-column element</div>
</div>
</div>

Nesting

It is possible to nest a Row within a Column in order to create a "nested grid".

jsx
<GridContainer>
<Row>
<Column span={6}>
<Row>
<Column span={3}>Nested content</Column>
</Row>
</Column>
</Row>
</GridContainer>

Note that it is not necessary to include another Grid Container. Simply adding another Row will do.

Columns don't have any special behavior when nested. They are always proportional to their Row's width. The nested (inner) grid will be divided into 12 new columns, proportional to the width of the nested (inner) grid.

That is: a 6-column element will always take up 6/12ths (50%) of its parent Row, no matter how wide that Row happens to be, and no matter how that Row happens to be nested.

Feel free to recursively nest these components as many times as you want. Just make sure that every Column is a direct child of a Row, and that every Row is a direct child of either a Grid Container or a Column.

Responsive

The grid's layout is adjustable for the different screen sizes that Visage defines:

  • Large - 1440 pixels or more (e.g. wide monitors)

  • Medium - 1024-1439 pixels (e.g. small monitors)

  • Small - 768-1023 pixels (e.g. tablets, some large phones in landscape)

  • Extra-Small - less than 768 pixels (e.g. most phones)

For a given Column component, you can change how many grid columns it spans at different screen sizes. You can also re-order Column elements within a given Row by "pushing" and "pulling" them leftward and rightward.

Resizing Columns

When you give a Column component a number of columns to span, by default it will have that width across all screen sizes — except for Extra-Small screens, where a Column component defaults to being 12 columns wide, so that the default layout on a phone is a single-column layout with no side-by-side content.

(For example, if you had two Columns each to set span 6 columns, they would be side-by-side on all screen sizes except for Extra-Small screens, where they would each take up the full width of the screen, and would end up stacked on top of one another.)

A Column can then override that value at specific screen sizes:

In React

To override at a given screen size, use the appropriate span* prop on a Column component:

  • span - sets the default size for the Column

  • spanXs - overrides the default size on xs screens (default:12)

  • spanSm - overrides the default size on sm screens

  • spanMd - overrides the default size on md screens

  • spanLg - overrides the default size on lg screens

This content has a default of 12/12ths (100%), and will use that value on Extra-Small and Small screens, but has overrides to take up 6/12ths (50%) of the width on Medium and Large screens
Share
Share
jsx

In Vanilla

To override at a given screen size, add the the appropriate col-X-N class to the col-N element, where "X" is the screen size (lgmdsm, or xs), and "N" is the number of columns.

For instance, to make a Column element take up 6 columns on Large screens, add the class col-lg-6 to it.

jsx
<div class="grid-container">
<div class="row">
<div class="col-12 col-md-6 col-lg-6">
This content has a default of 12/12ths (100%), and will use that value on
Extra-Small and Small screens, but has overrides to take up 6/12ths (50%)
of the width on Medium and Large screens
</div>
</div>
</div>

Reordering Columns

If columns in a row need to be re-ordered on a certain screen size, they can be "pushed" rightward or "pulled" leftward, based on the screen size. Use the pull* and push* properties to do this.

Note: pulls and pushes are ignored on Extra-Small screens.

In the example below, we have two Column elements that span 6 columns. For Medium and Large screens, we'll push the left-hand Column rightwards by 6 columns, and we'll pull the right-hand Column leftwards by 6 columns. The effect is that the Columns switch places on Medium and Large screens.

This on the left on Extra-Small and Small screens, but on the right on Medium and Large screens
Here's another column
Share
Share
jsx
<div class="grid-container">
<div class="row">
<div class="col-6 col-xs-6 col-md-push-6 col-lg-push-6">
This on the left on Extra-Small and Small screens, but on the right on
Medium and Large screens
</div>
<div class="col-6 col-xs-6 col-md-pull-6 col-lg-pull-6">
Here's another column
</div>
</div>
</div>

Offsets

Offsets let you indent a grid element, or widen the gap between elements. Offsets shift a block over to the right by a certain number of column widths. (This is generally preferable to creating empty space with an empty Column component.)

Offsets are ignored on Extra-Small screens.

Span 3/12
Span 7/12 with an offset of 2
Share
Share
jsx
<div class="grid-container">
<div class="row">
<div class="col-3">Content inside a 3-column element</div>
<div class="col-9 col-offset-2">Content inside a 9-column element</div>
</div>
</div>

Responsive Offsets

You can make an offset only occur for a certain screen size:

  • In React, use an offset* property. For instance, offsetSm will set an offset on Small screens.

  • In vanilla, use an col-offset-* class. For instance, col-offset-sm will set an offset on Small screens.

Grids as Lists

Often times Grid elements are semantically "list" elements. e.g. a Grid Container where each Row is an item in the shopper's cart, or a Row that is a list of tiles and each Column holds a tile.

It may be clear to sighted users that they're looking at a list of items, but that information will not be clear by default in the Accessibility Tree. In these cases, you can (and should) set the grid elements to be list elements (that is, <ul> and <li> tags.)

jsx
<GridContainer component="ul">
<Row component="li">
<Column span={12}>
<CartItem />
</Column>
</Row>
<Row component="li">
<Column span={12}>
<CartItem />
</Column>
</Row>
</GridContainer>

Flex Columns

A Flex Column will cause all of its direct children to be arranged vertically, spread out evenly between the top and bottom of the row (rather than all being aligned to the top). This is useful for keeping some elements aligned to the top and bottom of a taller neighboring element.

A
A
A
A
A
A
First child of B, where B is a Flex Column
Second child of B
C
C
C
Share
Share
jsx
jsx
<GridContainer>
<Row>
<Column span={4} flexColumn>
Flex Column contents go here
</Column>
</Row>
</GridContainer>
<div class="grid-container">
<div class="row">
<div class="col-4 col-flex-column">Flex Column contents go here</div>
</div>
</div>

Vertically Center

The "vertically center" option on a Column element will cause its contents to be vertically centered within the row, rather than being aligned to the top.

A
A
A
A
A
A
B is vertically centered
C
C
C
Share
Share
jsx
jsx
<GridContainer>
<Row>
<Column span={4} verticallyCenterContent>
contents of vertically centered element
</Column>
</Row>
</GridContainer>
<div class="grid-container">
<div class="row">
<div class="col-4 col-vertically-center">
contents of vertically centered element
</div>
</div>
</div>

Sticky Columns

Making a Column "sticky" means it will stay on screen as you scroll, so long as some other element in the same Row is also visible.

To make the stickiness function properly, the row will not vertically stretch all its columns to be the same height, as it normally does. This can affect the display of the columns in that row. For instance, if you are using a Card Container with the "even height" option, the cards in that row may not be all the same height.

Sticky coolumn
Column in the same row with really tall content
Share
Share
jsx
<div class="grid-container">
<div class="row row-sticky">
<div class="col-3 col-sticky">
<div class="background-medium-yellow py-9">Sticky column</div>
</div>
<div class="col-3">
<div class="background-opal" style="padding: 120px 0 700px 0">
Column in the same row with really tall content
</div>
</div>
</div>
</div>

You can also make a sticky column act normally (that is, not sticky) on Extra-Small screens. In React, add the unsticky="xs" to the Column element; in vanilla, JS, add the class col-unsticky-xs.

Tight Grids

The "tight" grid uses very narrow gutters between grid elements. It is intended only for use with Standard Tiles with the "gallery" skin.

Share
Share
jsx
jsx
<GridContainer gutter="tight">
<Row>
<Column span={4}>first element</Column>
<Column span={4}>second element</Column>
<Column span={4}>third element</Column>
</Row>
</GridContainer>
<div class="grid-container grid-container-tight">
<div class="row">
<div class="col-4">first element</div>
<div class="col-4">second element</div>
<div class="col-4">third element</div>
</div>
</div>

Floating Container

A Floating Container is a content container that has a width equal to a certain number of grid columns. It pins its contents to the left- or right-hand side of a Column element, with the rest of that parent's content flowing and wrapping around it.

A Floating Container is itself a Column element (but using the "floating container" option), and must be the direct child of a Column element.

Floating Containers are typically used for secondary content, such as a supporting image or pull quote. If the content of the floating container is secondary to the main text (as is usually the case), consider using a semantically-accurate <aside> tag instead of the default <div> for the floating container.

Floating container contents with a span of 6

A col-12 with additional text that should start to the right of the container, and wrap around the container so that it ends up below the container. (Except on Extra-Small screens, where all the text should sit below the container.) Here's some additional text to make this paragraph a little longer.

Floating container contents with a span of 4

This Floating Container is aligned to the right instead. Here's some additional text to make this paragraph a little longer. Here's some additional text to make this paragraph a little longer. Here's some additional text to make this paragraph a little longer. Here's some additional text to make this paragraph a little longer. Here's some additional text to make this paragraph a little longer.

Share
Share
jsx
<div class="grid-container">
<div class="row">
<div class="col-12">
<div class="col-6 floating-container">
Floating container contents with a span of 6
</div>
<p>
A col-12 with additional text that should start to the right of the
container, and wrap around the container so that it ends up below the
container. (Except on Extra-Small screens, where all the text should sit
below the container.) Here's some additional text to make this paragraph
a little longer.
</p>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="col-4 floating-container floating-container-right">
Floating container contents with a span of 4
</div>
<p>
This Floating Container is aligned to the right instead. Here's some
additional text to make this paragraph a little longer. Here's some
additional text to make this paragraph a little longer. Here's some
additional text to make this paragraph a little longer. Here's some
additional text to make this paragraph a little longer. Here's some
additional text to make this paragraph a little longer.
</p>
</div>
</div>
</div>

Components

GridContainer

PropTypeDefaultDescription
cardDividersboolean

Only applicable if the GridContainer is inside of a Card

Adds dividers between each Column

gutter"standard" | "tight"standard

The gutter width

All other props are forwarded to the element specified in thecomponentprop(default: <div/>)

Row

PropTypeDefaultDescription
stickyboolean

Whether the row allows sticky columns

All other props are forwarded to the element specified in thecomponentprop(default: <div/>)

Column

PropTypeDefaultDescription
spanXs1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 1212

The number of columns that this Column should occupy on extra-small screens

spanSm1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12

The number of columns that this Column should occupy on small screens

spanMd1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12

The number of columns that this Column should occupy on medium screens

spanLg1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12

The number of columns that this Column should occupy on large screens

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

The default number of columns that this column should be shifted to the right

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

The number of columns that this column should be shifted to the right on small screens

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

The number of columns that this column should be shifted to the right on medium screens

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

The number of columns that this column should be shifted to the right on large screens

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

Changes the default order in which the Columns are rendered by pushing this Column to the right by some number of columns

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

Changes the order in which the Columns are rendered on small screens by pushing this Column to the right by some number of columns

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

Changes the order in which the Columns are rendered on medium screens by pushing this Column to the right by some number of columns

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

Changes the order in which the Columns are rendered on large screens by pushing this Column to the right by some number of columns

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

Changes the default order in which the Columns are rendered by pulling this Column to the left by some number of columns

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

Changes the order in which the Columns are rendered on small screens by pulling this Column to the left by some number of columns

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

Changes the order in which the Columns are rendered on medium screens by pulling this Column to the left by some number of columns

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

Changes the order in which the Columns are rendered on large screens by pulling this Column to the left by some number of columns

flexColumnbooleanfalse

In a lineWrap GridContainer, whether or not to arrange the Column's children as a single column, spaced out evenly between the top and bottom

verticallyCenterContentbooleanfalse

Whether or not the Column's content should be vertically centered within the Row

stickyboolean'none'

Whether or not the Column's content should be sticky

unsticky"none" | "xs"'none'

If a Column is normally sticky, which screen sizes the Column should NOT be sticky on

floatingContainerbooleanfalse

Whether the Column is a Floating Container

floatingContainerAlignment"left" | "right"'left'

Whether Floating Container should float left or right

All other props are forwarded to the element specified in thecomponentprop(default: <div/>)

Guidelines

Design Guidelines

Do

  • Use only 3-column, 6-column, 9-column, and 12-column widths on Extra-Small and Small screens.

  • Use a nested grid to achieve greater design flexibility.

  • Specify the layout for each breakpoint at handoff.

Don't

  • Adjust the widths of columns, margins, and gutters.

  • Scale or stretch UI to fit the grid. Use components as intended for layout.

Developer Guidelines

Do

  • If you are placing one Column element inside another, put a Row element around the inner element, or a layout error may occur.

  • Place more than 12 columns' worth inside a single row, if you have a layout such as a long list of tiles. The grid elements will show the first 12 columns' worth, and then will line-wrap the rest of the content down onto the next row.

Don't

  • Put spacing, margin, padding, widths, or other layout-oriented styling onto layout grid elements, or a layout errors may occur when grid's code is changed in the future. If you need to add this styling to your content, put that styling on a wrapper element placed just inside the grid element.

  • Combine grid elements with other components, by putting a grid CSS class and another component's CSS class on the same HTML element. (For instance, don't make a Column component also be a Standard Section component.) Those other components may add spacing that will conflict with the grid component's spacing, and might alter the grid's display. Notable exception: you can put Background Color onto a grid element.

Accessibility Guidelines

  • If the grid elements are semantically part of a list, use <ul> and <li> tags as appropriate instead of <div> tags. For instance, if a row contains a sequence of product tiles, the row should be an <ul> tag, and the column elements should be <li> tags — because semantically, those tiles are a list.