Grid System

A grid provides a structure of rows and columns for aligning content. Grids are useful because they help create a familiar and easily navigable structure for content.

12 Column Grid

We use a 12 column grid for page-layout. It is currently based on flexbox which creates a flexible foundation for handling column-based layout. We use Susy as our math engine for grid-calculations. The grid-definition can be found in _conf_susy.scss.

Simple Syntax

Grids are built of three things: row, column, and content. This way the columns in a grid can be thought of as “buckets” for content, e.g. a component, widget or module.

<!-- ROW -->
<div class="kx-row">
    <!-- COLUMN -->
    <div class="kx-col">
        <!-- YOUR CONTENT -->
        <div>Content</div>
    </div>
</div>

It is recommended to give your grid some breathing space between itself and the viewport edges. By putting your grid HTML inside a <div class="kx-container">...</div> you get default padding on the left and right side. See Container for more details.

Fluid

Grids uses precentage-based values to make fluid widths. Gutters are handled using static values for padding (gutters inside). This way we can mix fluid columns with static gutters. Each column uses split-gutters. This means the padding is equal to a half gutter.

1
11
2
10
3
9
4
8
5
7
6
6
<div class="kx-row kx-row--gutters">
    <div class="kx-col kx-col--1">...<div>
    <div class="kx-col kx-col--11">...</div>
    <div class="kx-col kx-col--2">...</div>
    <div class="kx-col kx-col--10">...</div>
    <div class="kx-col kx-col--3">...</div>
    <div class="kx-col kx-col--9">...</div>
    <div class="kx-col kx-col--4">...</div>
    <div class="kx-col kx-col--8">...</div>
    <div class="kx-col kx-col--5">...</div>
    <div class="kx-col kx-col--7">...</div>
    <div class="kx-col kx-col--6">...</div>
    <div class="kx-col kx-col--6">...</div>
</div>

Automatic wrapping

Grid rows are set to automatically wrap if the columns do not fit a in a row. In this example a 4 column + a 10 column will exceed the maximum 12 column grid, hence the last column wraps to a new line.

4
10

Mix and match column widths to fit the 12 column grid. Here 4 + 8 = 12 🙌.

4
8

Responsive

Modifier-classes for responsive behavior enables you to specify column sizes at different viewport widths. Please note that these modifiers correspond to the breakpoints we have defined.

Try resizing your browser to see how the grid below changes based on viewport width.

Column
Column
Column
Column
Column
Column
Column
Column
Column

The convention for responsive grid classes can be a bit overwhelming at first, but you’ll see that it includes some syntactical sugar that makes it quite logical.

The convention is: [namespace]-col--[columns][@scope].

Here is an example:

<div class="kx-row kx-row--gutters">
    <div class="kx-col kx-col--12 kx-col--6@mob-m kx-col--4@tab-m kx-col--3@ltp-s">
        <div>Responsive</div>
    </div>
</div>

The example above can be read like: “This column should be…”:

  • kx-col--1212 of 12 columns wide (100%) at all screen sizes, but…
  • kx-col--6@mob-m6 of 12 columns wide (50%) at screens > medium mobile, but…
  • kx-col--4@tab-m4 of 12 columns wide (33%) at screens > medium tablet, but…
  • kx-col--3@ltp-s3 of 12 columns wide (25%) at screens > small laptop

and it looks like this (try resizing your browser):

Responsive

Gutters

To handle gutters, we use the kx-row-element. By adding modifiers to this, we can create grids with/without gutters, or even gutters only in one direction.

In addition to the base class kx-row, add modifiers for:

  • kx-row--gutters: standard gutters both horizontally and vertically.
  • kx-row--gutters-v: standard gutters vertically.
  • kx-row--gutters-h: standard gutters horizontally.

Gutters: none

kx-row

Column
Column
Column
Column
Column
Column
<div class="kx-row">
    <div class="kx-col kx-col--12 kx-col--4@tab-l">
        <div>Column</div>
    </div>
    ...
    ..
</div>

Gutters: horizontally + vertically

kx-row--gutters

Column
Column
Column
Column
Column
Column
<div class="kx-row kx-row--gutters">
    <div class="kx-col kx-col--12 kx-col--4@tab-l">
        <div>Column</div>
    </div>
    ...
    ..
</div>

Gutters: horizontally

kx-row--gutters-h

Column
Column
Column
Column
Column
Column
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--12 kx-col--4@tab-l">
        <div>Column</div>
    </div>
    ...
    ..
</div>

Gutters: vertically

kx-row--gutters-v

Column
Column
Column
Column
Column
Column
<div class="kx-row kx-row--gutters-v">
    <div class="kx-col kx-col--12 kx-col--4@tab-l">
        <div>Column</div>
    </div>
    ...
    ..
</div>

Auto Width

If you don’t include modifiers for width, the grid will auto-fit the width of the columns to fit a row. Here we just have one column, but without modifiers for width. It default “grows” to fill the available space.

I’m automatic 100%
<div class="kx-row kx-row--gutters">
    <div class="kx-col">
        <div>I'm automatic 100%</div>
    </div>
</div>

Here we have two columns, also without modifiers for width. They share the available space, each becoming 50% wide.

I’m automatic 50%
I’m automatic 50%
<div class="kx-row kx-row--gutters">
    <div class="kx-col">
        <div>I'm automatic 50%</div>
    </div>
    <div class="kx-col">
        <div>I'm automatic 50%</div>
    </div>
</div>

Nested Grids

Yes! Grids can be nested. Just remember to use the modifier kx-row--gutters together with the base class kx--row on the parent wrapping your inner columns kx-col. Double gutters are removed due to the the negative margins applied with kx-row--gutters. But really consider if you need nested grids. The HTML structure can quickly become cumbersome and hard to manage.

Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.

Ian Malcom (Jurassic Park)
Parent
Child
Grandchild
Grandchild
Grandchild
Child
Grandchild
Great Grandchild
Great Grandchild

Alignment

Add flexbox utility classes to rows for aligning it’s children to the start, center, end, top, middle or bottom. These classes are also responsive, so the alignment can change on different viewports.

Horizontal alignment

kx-justify-content-start (horizontal left)

Box
<div class="kx-row kx-row--gutters-h kx-justify-content-start">
    <div class="kx-col kx-col--6">
        <div>Box</div>
    </div>
</div>

kx-justify-content-center (horizontal center)

Box
<div class="kx-row kx-row--gutters-h kx-justify-content-center">
    <div class="kx-col kx-col--6">
        <div>Box</div>
    </div>
</div>

kx-justify-content-end (horizontal right)

Box
<div class="kx-row kx-row--gutters-h kx-justify-content-end">
    <div class="kx-col kx-col--6">
        <div>Box</div>
    </div>
</div>

Example: responsive horizontal alignment

Here is an example of different alignments on different viewport sizes. All modifier classes corresponds to the defined breakpoints.

  • Start alignment on mobile-sized viewport.
  • End alignment on tablet-sized viewport.
  • Center alignment on laptop-sized viewport.
Responsive alignment
<div class="kx-row kx-row--gutters-h kx-justify-content-left kx-justify-content-end@tab-s kx-justify-content-center@ltp-s">
    <div class="kx-col kx-col--4">
        <div>Responsive alignment</div>
    </div>
</div>

Vertical alignment

kx-align-items-start (vertical top)

Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
Short text
<div class="kx-row kx-row--gutters-h kx-align-items-start">
    <div class="kx-col kx-col--6">
        <div>Long text Long text...</div>
    </div>
    <div class="kx-col kx-col--6">
        <div>Short text</div>
    </div>
</div>

kx-align-items-center (vertical middle)

Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
Short text
<div class="kx-row kx-row--gutters-h kx-align-items-center">
    <div class="kx-col kx-col--6">
        <div>Long text Long text...</div>
    </div>
    <div class="kx-col kx-col--6">
        <div>Short text</div>
    </div>
</div>

kx-align-items-end (vertical bottom)

Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
Short text
<div class="kx-row kx-row--gutters-h kx-align-items-end">
    <div class="kx-col kx-col--6">
        <div>Long text Long text...</div>
    </div>
    <div class="kx-col kx-col--6">
        <div>Short text</div>
    </div>
</div>

Example: responsive vertical alignment

In this example, focus on the second box containing the short text. Try resizing your browser. You’ll notice that it changes position based on the viewport size;

  • Middle alignment on mobile-sized viewport.
  • Bottom alignment on tablet-sized viewport.
  • Top alignment on laptop-sized viewport.
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
Short text

Distribution

Use flexbox utilities on kx-row to distribute columns across the available space.

kx-justify-content-around (space around)

Box
Box
Box
<div class="kx-row kx-row--gutters-h kx-justify-content-around">
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
</div>

kx-justify-content-between (space between)

Box
Box
Box
<div class="kx-row kx-row--gutters-h kx-justify-content-between">
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
</div>

Auto margins

Since our grid rows uses flexbox (flex containers), we can utilize auto margins to get granular layout control over our grid columns (flex items). Please see flexbox utilities and spacing for more details on auto margins. The icons ⏪ and ⏩ indicate the direction of the auto margins.

Box ⏩
Box
Box
Box
⏪ Box ⏩
Box
Box
Box
⏪ Box
Box ⏩
Box
Box
⏪ Box
<!-- 1st row -->
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--2 kx-mr--auto">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
</div>

<!-- 2nd row -->
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2 kx-mx--auto">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
</div>

<!-- 3rd row -->
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2 kx-ml--auto">
        <div>Box</div>
    </div>
</div>

<!-- 4th row -->
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--2 kx-mr--auto">
        <div>Box ⏩</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--2 kx-ml--auto">
        <div>⏪ Box</div>
    </div>
</div>

Offset

You can offset a column to either the left or right.

Box
Box
Box
Box
Box
Box
Box
Box
Box
Box
Box
<div class="kx-row kx-row--gutters">
    <div class="kx-col kx-col--1 kx-offset-11">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--1 kx-offset-10">
        <div>Box</div>
    </div>
    <div class="kx-col kx-col--1 kx-offset-9">
        <div>Box</div>
    </div>
    ...
    ..
    .
</div>

Here is another example:

Short text offset by 1 column
Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text Long text
Short text
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--2 kx-offset-1">
        <div>Short text offset by 1 column</div>
    </div>
    <div class="kx-col kx-col--6">
        <div>
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
            Long text Long text Long text Long text Long text
        </div>
    </div>
    <div class="kx-col kx-col--2">
        <div>Short text</div>
    </div>
</div>

Reversing

Add flexbox utilities on kx-row to reverse the order of columns. Please note that columns are automatically aligned to the visual end of the row (right). This is default behavior with the flex-direction: reverse; declaration.

1
2
3
<div class="kx-row kx-row--gutters-h kx-flex-row-reverse">
    <div class="kx-col kx-col--2">
        <div>1</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>2</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>3</div>
    </div>
</div>

To re-align the reverse-ordered columns to the visual start of the row (left), please add kx-justify-content-end to the row element as well. Since the row is reversed, the end becomes the visual start.

1
2
3
<div class="kx-row kx-row--gutters-h kx-flex-row-reverse kx-justify-content-end">
    <div class="kx-col kx-col--2">
        <div>1</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>2</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>3</div>
    </div>
</div>

Reordering

You can reorder columns with two utility classes: --first and --last. These classes are responsive, so you can choose when (on which viewport-size) a column shall be first or last.

1
2
3
<div class="kx-row kx-row--gutters-h">
    <div class="kx-col kx-col--2 kx-col--last">
        <div>1</div>
    </div>
    <div class="kx-col kx-col--2 kx-col--first">
        <div>2</div>
    </div>
    <div class="kx-col kx-col--2">
        <div>3</div>
    </div>
</div>

Responsive variations available for kx-col--first

  • kx-col--first[@mob-s|@mob-m|tab-s|@tab-m|@tab-l|@ltp-s|@ltp-m|@dtp]
  • Example: kx-col--first@mob-s

Responsive variations available for kx-col--last

  • kx-col--last[@mob-s|@mob-m|tab-s|@tab-m|@tab-l|@ltp-s|@ltp-m|@dtp]
  • Example: kx-col--last@mob-s

Note: Reversing and reordering will change the visual order of element from the actual source order in the Document Object Model. This might lead to confusing situations when tabbing through the page. Read more about Flexbox & the keyboard navigation disconnect

Resources