Skip to main content

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>