Skip to main content
U.S. flag

An official website of the United States government

CMS Design System

Grid

The design system provides a 12-column, responsive, flexbox grid to provide structure and align content.

The grid consists of three distinct pieces:

  • A container adds a maximum width and centers the content
  • A row enables the flexbox layout and holds between 1-12 columns

Installation

The grid is opt-in and not distributed with the core design system package. Install the NPM package or download the latest release.

npm install @cmsgov/design-system-layout --save

View the package's README for additional info.

Browser support

Flexbox grid supports modern browsers and Internet Explorer 10+. In older versions of Internet Explorer the grid columns will be stacked.

Default behavior

Columns without a set width will automatically layout with equal widths. For example, below are four instances of .ds-l-col which are each automatically 25% wide. The columns will automatically wrap when they don't fit a single row.

Column widths are set in percentages, so they’re always responsive and will be sized relative to their parent row.

Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row">
    <div class="ds-l-col">
      Equal
    </div>
    <div class="ds-l-col">
      Equal
    </div>
    <div class="ds-l-col">
      Equal
    </div>
    <div class="ds-l-col">
      Equal
    </div>
  </div>
</section>

Specifying number of columns

Specify the number of columns (1-12) to span using .ds-l-col--* classes. These classes will span * columns. So, if you want two elements that each span half the row, you would use .ds-l-col--6

Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row">
    <div class="ds-l-col--6">
      6 columns
    </div>
    <div class="ds-l-col--6">
      6 columns
    </div>
  </div>
</section>

Natural width columns

Use a .ds-l-col--auto class to size a column to the natural width of its content.

Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row">
    <div class="ds-l-col--auto">
      1 of 3
    </div>
    <div class="ds-l-col--auto">
      A little bit longer text
    </div>
    <div class="ds-l-col--auto">
      3 of 3
    </div>
  </div>
</section>

Mobile, tablet, and desktop grids

Each column class can include a breakpoint "prefix" (sm, md, lg, xl), allowing you to change the column widths based on the viewport width.

An element with a ds-l-{breakpoint}-col--* class will span * columns at viewports matching breakpoint and larger.

In the example below, the cells span:

  • 1/6 of the row on xl viewports, using ds-l-xl-col--2
  • 1/4 of the row on lg viewports, using ds-l-lg-col--3
  • 1/3 of the row on md viewports, using ds-l-md-col--4
  • 1/2 of the row on sm viewports, using ds-l-sm-col--6
  • The entire width of the row on viewports smaller than the sm breakpoint, using ds-l-col--12
New tab
Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row">
    <div class="ds-l-col--12 ds-l-sm-col--6 ds-l-md-col--4 ds-l-lg-col--3 ds-l-xl-col--2">
      A
    </div>
    <div class="ds-l-col--12 ds-l-sm-col--6 ds-l-md-col--4 ds-l-lg-col--3 ds-l-xl-col--2">
      B
    </div>
    <div class="ds-l-col--12 ds-l-sm-col--6 ds-l-md-col--4 ds-l-lg-col--3 ds-l-xl-col--2">
      C
    </div>
    <div class="ds-l-col--12 ds-l-sm-col--6 ds-l-md-col--4 ds-l-lg-col--3 ds-l-xl-col--2">
      D
    </div>
    <div class="ds-l-col--12 ds-l-sm-col--6 ds-l-md-col--4 ds-l-lg-col--3 ds-l-xl-col--2">
      E
    </div>
    <div class="ds-l-col--12 ds-l-sm-col--6 ds-l-md-col--4 ds-l-lg-col--3 ds-l-xl-col--2">
      F
    </div>
  </div>
</section>

Nested grids

Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row">
    <div class="ds-l-col--9">
      Level 1
      <div class="ds-l-row">
        <article class="ds-l-col--4">
          Level 2
        </article>
        <article class="ds-l-col--4">
          Level 2
        </article>
        <article class="ds-l-col--4">
          Level 2
        </article>
      </div>
    </div>
    <div class="ds-l-col--3">
      Level 1
    </div>
  </div>
</section>

Offsetting columns

Offset columns using the margin auto utility class:

Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row">
    <div class="ds-l-col--3">
      3 columns
    </div>
    <div class="ds-l-col--4 ds-u-margin-left--auto">
      4 columns, offset 5 columns
    </div>
  </div>
</section>

Alignment

Align columns horizontally or vertically using flexbox utility classes. To align columns horizontally, use the justify-content utility class. To align columns vertically, use the align-items utility class.

Code snippet
<section class="ds-l-container preview__grid">
  <div class="ds-l-row ds-u-fill--gray">
    <div class="ds-l-col--3">Left</div>
  </div>
  <div class="ds-l-row ds-u-justify-content--center ds-u-fill--gray">
    <div class="ds-l-col--3">Center</div>
  </div>
  <div class="ds-l-row ds-u-justify-content--end ds-u-fill--gray">
    <div class="ds-l-col--3">Right</div>
  </div>
  <div class="ds-l-row ds-u-align-items--start ds-u-fill--gray ds-u-margin-y--2" style="height: 125px">
    <div class="ds-l-col--3">Top</div>
    <div class="ds-l-col--3">Top</div>
    <div class="ds-l-col--3">Top</div>
  </div>
  <div class="ds-l-row ds-u-align-items--center ds-u-fill--gray ds-u-margin-y--2" style="height: 125px">
    <div class="ds-l-col--3">Center</div>
    <div class="ds-l-col--3">Center</div>
    <div class="ds-l-col--3">Center</div>
  </div>
  <div class="ds-l-row ds-u-align-items--end ds-u-fill--gray ds-u-margin-y--2" style="height: 125px">
    <div class="ds-l-col--3">Bottom</div>
    <div class="ds-l-col--3">Bottom</div>
    <div class="ds-l-col--3">Bottom</div>
  </div>
</section>

Forms

Use a .ds-l-form-row class to tighten the column spacing when laying out form fields in a grid.

Code snippet
<section class="preview__grid">
  <div class="ds-l-form-row">
    <div class="ds-l-col--auto">
      <label class="ds-c-label ds-u-margin-top--0" for="city">City</label>
      <input class="ds-c-field" type="text" id="city" name="city">
    </div>
    <div class="ds-l-col--auto">
      <label class="ds-c-label ds-u-margin-top--0" for="state">State</label>
      <input class="ds-c-field" type="text" id="state" name="state">
    </div>
  </div>
</section>

Guidance

When to use

  • Almost always use a grid layout — visitors can read more quickly on pages that use grids. Choose a single grid system for your entire site.

When to consider alternatives

  • Avoid mixing this grid and other grid systems.

Usage

  • Choose a 12-column grid with flexible column widths and fixed gutters.
  • Avoid text lines longer than 75 characters. Place text in narrower columns to keep text lines from becoming too wide or use the measure utility classes.

Accessibility

  • Low-vision users should be able to increase the size of the text by up to 200 percent without breaking the layout.
  • The DOM order and visual presentation of content should be consistent, in order to not break keyboard navigation. This means you should avoid changing the flexbox order property of the grid columns.

Customization

The following Sass variables can be overridden to customize the grid:

  • $grid-columns
  • $grid-gutter-width

Learn more