Jump to main content

Accurate Content Columns

The .column-{*} classes provide precise control over each column's span, with fractions based on the total container width. Remember to always wrap them in a .row.

File location: sass/layout/_accurate-columns.scss (GitHub)

hgrid splits the viewport into 24 equal fractional units.

  • .column-1 is a full width column that spans all 24 units.
  • .column-2 spans 12 units, or 50% of the viewport width.
  • .column-3 spans 8 units (33,33%) ...
  • ... and so on up to .column-24 (4.1667%).

By combining fractional units we now get a precisely controlled layout grid:

<div class="row">
  <div class="column-2">
    <p>.column-2</p>
  </div>
  <div class="column-4">
    <p>.column-4</p>
  </div>
  <div class="column-4">
    <p>.column-4</p>
  </div>
</div>

The code above results in one column spanning 2/4 and two columns spanning 1/4, for a total of 4/4, or 100%, of the parent container.

.column-2

.column-4

.column-4

Note: These columns would normally stack vertically on devices with with viewport width up to 768 pixels. For the sake of the examples on this page, we have applied .no-stack after .row so they make sense for readers on any device.

Column Stacking

Accurate columns stack vertically on screens less than 769px wide. The breakpoint is determined by the variable $stack-point which is equal to the width set in $phone-landscape. You can modify this in the @use rule when initializing hgrid.

Prevent Column Stacking

Prevent column stacking by adding .no-stack to the row like this: <div class="row no-stack">.

Remove Column Gutters

Remove margins between columns (aka. gutters) with the override class .no-gutter on the row element. Or add it to individual columns if you want to remove gutters from only those elements.

<div class="row no-gutter">
  <div class="column-2"></div>
  <div class="column-2"></div>
</div>

<!-- or -->

<div class="row">
  <div class="column-2 no-gutter"></div>
  <div class="column-2 no-gutter"></div>
</div>

Result:

column-2

column-2

Nesting

Containers can be nested inside of each other as long as you wrap each level in a new .row. If you nest a .column-2 inside of another .column-2, the width of the inner column will be half of the outer. The parent element always acts as its children's new 'viewport' context and is fractionable into 24 equal parts.

Containers can be nested inside each other as long as you wrap each new level in a new .row.

<div class="row">
  <div class="column-2 border-gray padding-5 radius-8"></div>
  <div class="column2 border-gray padding-5 radius-8">
    <div class="row margin-bottom-0">
      <div class="column-2 padding-10 bg-gray-light text-center">.column-2</div>
      <div class="column-2 padding-10 bg-gray-light text-center">.column-2</div>
    </div>
  </div>
</div>
.column-2
.column-2
.column-2
.column-2

As seen here, if we nest two .column-2 inside of another .column-2, the width of the inner columns will be half of the outer one. For each level we nest, the parent element act as the new "viewport" width to be split in 24 hgrid units.

Filling Up

Accurate columns don't have to add up to 24 units/100% width. Use .column-fill to fill the remaining space in the .row, or just keep the space open.

If you fill a .row with columns adding up to more than 24 units, each will be squeezed to fit, while their proportions relative to their siblings is preserved. A squeezed .column-3 is still twice as wide as a squeezed .column-6.

Below we see examples of rows filled up entirely by columns adding up to 100% width, a row whose columns add up to <100%, and one row where the remaining space hass been filled with the elastic .column-fill.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

.column-6

.column-2

.column-6

.column-6

.column-10

.column-7

.column-11

.column-11

.column-3

.column-12

.column-fill

Note: The example above would normally stack vertically on devices < 768 pixels wide. We have applied .no-stack after .row so it makes sense for readers on any device.

Responsive Column Wrapping

Accurate columns will wrap on to new lines if .f-wrap has been added (<div class="row f-wrap">) and the columns combined exceed the row width.

Wrapping occurs as a result of the following:

  • A responsive utility (see below), for example .phone-landscape-2, has been added to one or more columns, making the combined width exceed the row width on a specific viewport (in this case the phone-landscape viewport).
  • A min-width or a fixed width has been applied to at least one column, and has made the combined column width exceed the full row width.
  • The column widths in percent add up to more than 100%. With .f-wrap rows won't allow any excess like they usually do.

Example:

<div class="row no-stack f-wrap">
  <div class="column-2">1</div>
  <div class="column-2">2</div>
  <div class="column-4">3</div>
  <div class="column-4">4</div>
</div>

1

2

3

4

Media Query Utilities

The media query utilities follow this naming convention:

.{ viewport_name }-{ fraction }

Example: .tablet-portrait-4

They apply to the viewport referenced by their name (and smaller, except for .desktop and .desktop-large that apply to screens wider than 1281px and 1680px respectively. The utilities are particularly useful combined with .f-wrap on their parent row.

Let's add .tablet-landscape-1 to one of the .column-2 from the previous example. This means that this column will go from taking up half of the viewport to full width on tablets in landscape mode and below (<1024px). Other columns will be forced to wrap on to new lines because of .f-wrap on the parent element.

Let's add a setting for phone-landscape, too. The same column now grows from 50% of the row width on laptops, to 100% on wide tablets, and down to 25% on wide phone screens. Other columns will remain unaffected.

<div class="row no-stack f-wrap">
  <div class="column-2 tablet-landscape-1 phone-landscape-4">1</div>
  <div class="column-2">2</div>
  <div class="column-4">3</div>
  <div class="column-4">4</div>
</div>

Result (resize your browser):

1

2

3

4

Media query utilities don't allow their columns to be squeezed to less than their actual width in a .f-wrap context. Fractions go from 1 to 12. All viewports are covered, except the default laptop.

.desktop-large-1, .desktop-large-2 .... .desktop-large-12
.desktop-1, .desktop-2 .... .desktop-12
.tablet-landscape-1, .tablet-landscape-2 .... .tablet-landscape-12
.tablet-portrait-1, .tablet-portrait-2 .... .tablet-portrait-12
.phone-landscape-1, .phone-landscape-2 .... .phone-landscape-12
.phone-1, .phone-2 .... .phone-12

Previous: Automatic Columns

Next: Flex