Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1122397 of Grids

  • Revision slug: Learn/CSS/CSS_layout/Grids
  • Revision title: Grids
  • Revision id: 1122397
  • Created:
  • Creator: chrisdavidmills
  • Is current revision? No
  • Comment

Revision Content

{{draft}}{{LearnSidebar}}
{{PreviousMenuNext("Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout/Assessment", "Learn/CSS/CSS_layout")}}

Grids are an established design tool, and many modern website layouts are based on a regular grid. In this article we’ll take a look at grid-based design, and how CSS can be used to create grids — both with current tools, and new technology that is just starting to become available in browsers.

Prerequisites: HTML basics (study Introduction to HTML), and an idea of How CSS works (study Introduction to CSS and Styling boxes.)
Objective: To understand the fundamental concepts behind grid layout systems, and how to implement a grid layout on a web page.

What is grid layout?

A grid is simply a collection of horizontal and vertical lines creating a pattern against which we can line up our design elements. They help us to create designs where elements don’t jump around or change width as we move from page to page, providing greater consistency on our websites.

A grid will typically have columns, rows, and then gaps between each row and column — often referred to as gutters.

[PROVIDE A DIAGRAM DETAILING THE MAIN ELEMENTS OF A GRID SYSTEM]

[Temporary diagram; will be replaced by a better diagram soon.]

Note: It may seem surprising to anyone coming from a design background that CSS doesn’t have an inbuilt grid system, and instead we seem to be using a variety of suboptimal methods to create grid-like designs. As you’ll discover in the last part of this article this is set to change, however you are likely to need to know the existing methods of creating grids for some time to come.

Using a “grid system” in your projects

In order to ensure a consistent experience across your site or application, basing it upon a grid system from the outset means you don’t need to think about how wide a certain element is in relation to the other elements. Your choice is limited to “how many columns of the grid this element will span”.

Your “grid system” could simply be a decision made in the design process to use a regular grid. If your designs start life in an application such as Photoshop you can create a grid to reference during that process as described in A better Photoshop grid for responsive web design by Elliot Jay Stocks.

Your grid system may also be a framework — either third party or created by you just for your project — that you use to enforce the grid via CSS.

Creating simple grid frameworks

We will start by having a look at how you might create a simple grid framework for your project.

At the present time the majority of grid type layouts are created using floats. If you have read our previous article about floats you’ve already seen how we can use this technique to create a multiple column layout — which is the essence of any grid system using this method.

The easiest type of grid framework to create is a fixed width one — we just need to work out how much total width we want our design to be, how many columns we want, and how wide the gutters and columns should be. If we instead decided to lay out our design on a grid with columns that grow and shrink according to browser width we would need to calculate percentage widths for the columns and  gutters between them.

In the next sections we will look at how to create both. We will create a 12 column grid — a very common choice that is seen to be very adaptable to different situations given that 12 is nicely divisible by 6, 4, 3, and 2.

A simple fixed width grid

Lets first create a grid system that uses fixed width columns.

1. Start out by making a local copy of our sample simple-grid.html file, which contains the following markup in its body.

<div class="wrapper">
  <div class="row">
    <div class="col">1</div>
    <div class="col">2</div>
    <div class="col">3</div>
    <div class="col">4</div>
    <div class="col">5</div>
    <div class="col">6</div>
    <div class="col">7</div>
    <div class="col">8</div>
    <div class="col">9</div>
    <div class="col">10</div>
    <div class="col">11</div>
    <div class="col">12</div>
  </div>
  <div class="row">
    <div class="col span1">13</div>
    <div class="col span6">14</div>
    <div class="col span3">15</div>
    <div class="col span2">16</div>    
  </div>
</div>

The aim is to turn this into a demonstration grid of two rows on a twelve column grid — the top row demonstrating the size of the individual columns, the second row some different sized areas on the grid.

[INSERT IMAGE OF FINISHED EXAMPLE]

2. In the {{htmlelement("style")}} element, add the following code, which first makes all the elements on the page sized as border boxes and then gives the wrapper container a width of 980 pixels, with padding on the right hand side of 20 pixels. This leaves us with 960 pixels for our total column/gutter widths.

* { box-sizing: border-box; }
    
.wrapper {
  width: 980px;
  margin: 0 auto;
  padding-right: 20px;
}

3. Now use the row container that is wrapped around each row of the grid to clear one row from another. Add the following rule below your previous one:

```
    .row {
      clear: both;
    }
```

This clearing means that we don’t need to completely fill each row with elements making the full twelve columns. The rows will remaining separated, and not interfere with each other.

The gutters between the columns are 20 pixels wide. We create these gutters as a margin on the left side of each column - including the first column. This will then balance out the 20 pixels of padding on the right side of the container. So we have 12 gutters in total - 12 x 20 = 240.

We need to subtract that from our total width of 960 pixels, giving us 720 pixels for our columns. If we now divide that by 12, we know that each column should be 60 pixels wide.

4. Our next step is to create rules for the class ‘.col’,  floating it left, giving it a margin-left of 20 pixels to form the gutter, and a width of 60px. The top row of single columns will now lay out neatly as a grid.

Note: We've also given each column a light red color so you can see exactly how much space each one takes up.

Add the following rule to the bottom of your CSS:

.col {
  float: left;
  margin-left: 20px;
  width: 60px;
  background: rgb(255,150,150);
}

5. To enable layout containers that span more than one column, we will need to create some additional classes to allow them to span 2 to 12 columns. We do this by adding up the column width of that number of columns plus the gutter widths.

Add the following at the bottom of your CSS:

```
    /* Two column widths (120px) plus one gutter width (20px) */
  .col.span2 { width: 140px; }
  /* Three column widths (180px) plus two gutter widths (40px) */
    .col.span3 { width: 220px; }
  /* And so on... */
    .col.span4 { width: 300px; }
    .col.span5 { width: 380px; }
    .col.span6 { width: 460px; }
    .col.span7 { width: 540px; }
    .col.span8 { width: 620px; }
    .col.span9 { width: 700px; }
    .col.span10 { width: 780px; }
    .col.span11 { width: 860px; }
    .col.span12 { width: 940px; }
```

6. With these classes created we can now lay out different width columns on my grid. Try saving and loading the page in your browser to see the effects.

Note: If you are having trouble getting the above example to work, try comparing it against our finished version on GitHub (see it running live also).

7. Try modifying the classes on your elements and even adding and removing some containers, to see how you can vary the layout. For example, you could make the second row look like this:

```
    <div class="row">
        <div class="col span8">13</div>
        <div class="col span4">14</div>
     </div>
```

Now you've got a grid system working, you can simply define the rows and the number of columns in each row, then fill each container with your required content.

### Creating a fluid grid

Our grid works nicely, but it is fixed width. We really want a flexible (fluid) grid that will grow and shrink with the available space in the browser viewport. To achieve this we can use the reference pixel widths and turn them into percentages.

The equation that turns a fixed width into a flexible percentage-based one is as follows.

target / context = result

For our column width, our _target width_ is **60 pixels** and our _context_ is the **960 pixel** wrapper. We can use the following to calculate a percentage.

60 / 960 = 0.0625

We then move the decimal point 2 places, giving us a percentage of 6.25%. In our CSS we can replace 60 pixels with 6.25%.

We need to do the same with our margin.

20 / 960 = 0.02083333333

So we need to replace the 20 pixel marign-left on our .col rule, and the right hand padding on .wrapper, with 2.08333333%.

1. To get started in this section, make a new copy of your previous example page, or use our simple-grid-finished.html code as a starting point.

2. Replace the second CSS rule (with the .wrapper selector) as follows:

.wrapper {
  width: 90%;
  max-width: 980px;
  margin: 0 auto;
  padding-right: 2.08333333%;
}

Not only have we given it a width as a percentage, we have  also added a `max-width` property in order to stop the layout becoming too wide.

3. Next, replace the fourth CSS rule (with the .col selector) like so:

.col {
  float: left;
  margin-left: 2.08333333%;
  width: 6.25%;
  background: rgb(255,150,150);
}

4. Now comes the slightly more laborious part — we need to update all our .col.span rules to use percentages rather than pixel widths. This takes a bit of time with a calculator; to save you some effort, we've done it for you below.

Update the bottom block of CSS rules with the following:

/* Two column widths (12.5%) plus one gutter width (2.08333333%) */
.col.span2 { width: 14.58333333%; }
/* Three column widths (18.75%) plus two gutter widths (4.1666666) */
.col.span3 { width: 22.91666666%; }
/* And so on... */
.col.span4 { width: 31.24999999%; }
.col.span5 { width: 39.58333332%; }
.col.span6 { width: 47.91666665%; }
.col.span7 { width: 56.24999998%; }
.col.span8 { width: 64.58333331%; }
.col.span9 { width: 72.91666664%; }
.col.span10 { width: 81.24999997%; }
.col.span11 { width: 89.5833333%; }
.col.span12 { width: 97.91666663%; }

5. Save your code, load it in a browser, and try changing the viewport width — you should see the column widths adjust nicely to suit. Great!

Note: If you are having trouble getting the above example to work, try comparing it against our finished version on GitHub (see it running live also).

Easier calculations using the calc() function

You could use the `calc()` function to do the math right inside your CSS. Let’s have a look at how calc() works. (CHECK TO SEE IF I'VE COVERED THIS ANYWHERE ELSE ALREADY)

Any column that spans more than one column of our grid is a total width of 6.25 multiplied by the number of columns spanned plus 2.08333333 multiplied by the number of gutters (which will always be the number of columns minus 1). The calc function means we can do this as the value of width, so for anY item spanning 4 columns we can do this, for example:

```
    .col.span4 {
      width: calc((6.25%*4) + (2.08333333%*3));
    }
```

Try replacing your bottom block of rules with the following, then reload it in the browser to see if you get the same result:

.col.span2 { width: calc((6.25%*2) + 2.08333333%); }
.col.span3 { width: calc((6.25%*3) + (2.08333333%*2)); }
.col.span4 { width: calc((6.25%*4) + (2.08333333%*3)); }
.col.span5 { width: calc((6.25%*5) + (2.08333333%*4)); }
.col.span6 { width: calc((6.25%*6) + (2.08333333%*5)); }
.col.span7 { width: calc((6.25%*7) + (2.08333333%*6)); }
.col.span8 { width: calc((6.25%*8) + (2.08333333%*7)); }
.col.span9 { width: calc((6.25%*9) + (2.08333333%*8)); }
.col.span10 { width: calc((6.25%*10) + (2.08333333%*9)); }
.col.span11 { width: calc((6.25%*11) + (2.08333333%*10)); }
.col.span12 { width: calc((6.25%*12) + (2.08333333%*11)); }

Note: You can see our version in fluid-grid-calc.html (also see it live).

Note: If you can't get this to work, it might be because your browser does not support the calc() function — it is a fairly recent addition to browsers, which works in [ADD BROWSER SUPPORT STATS]

### Semantic versus “un-semantic” grid systems

Adding classes to your markup to define layout does mean that your content and markup becomes tied to the visual presentation. You will sometimes hear this use of CSS classes described as being “un-semantic”, rather than a semantic use of classes that describes the content rather than how the content looks.

You do not need to add the span2, span3 etc. classes to your markup. You could instead decide on your grid and then add the sizing information to the rules for existing - semantic - classes. For example, I have a div with a class of content that I want to span 8 columns and so I copy across the width from the `span8` class:

```
    .content {
      width: calc((6.25%*8) + (2.08333333%*7));
    }
```

If you use a preprocessor such as Sass then you could create a simple mixin to insert that value for you.

### Limitations of our grid

The grid we have created works well as long as we want to start all of the rows flush with the left hand side of the grid. If we wanted to leave a gap before the first item we would need to create an offset class adding a left margin to our site to push it across the grid visually. More math!

Let's try this out.

1. Start with your previous code, or use our fluid-grid.html file as a starting point.

2.  Let's create a class in our CSS that will offset a container element by one column width. Add the following to the bottom of your CSS:

```
    .offset-by-one {
      margin-left: calc(6.25% + (2.08333333%*2));
    }
```

Or if you are prefer to calculate the percentages yourself, use this one:

```
  .offset-by-one {
    margin-left: 10.41666666%;
  }
```

3. You can now add this class to any container you want, to leave a one column width gap on the left hand side of it. For example, if you have this in your HTML:

<div class="col span6">14</div>

Try replacing it with

<div class="col span5 offset-by-one">14</div>

Note: Notice that you need to reduce the number of columns spanned, to make room for the offset!

4. Try loading and refreshing to see the difference, or check out our fluid-grid-offset.html example (see it running live also).

Note: As an extra exercise, can you implement an offset-by-two class?

Floated grid limitations

When using a system like this you do need to take care that your total widths add up correctly, and that you don’t include elements in a row that span more columns than the row cna contain. Due to the way floats work, if your total width becomes wider than 100% the excess items will drop to the next line.

If the content of the elements pushes them to become wider this will also make the total width more than 100% and the same thing will happen.

The container div with a class of row helps to prevent our design falling into chaos should our lines not add up neatly to 100% but you do need to do a fair amount of managing of the grid when using this method. Commonly you would use media queries to create a different layout at narrower breakpoints to ensure that you don’t have the issue of the grid pushing too wide.

An additional limitation of this system is that it is essentially one dimensional. We are dealing with columns, and spanning elements across columns, but not rows. It is very difficult with these older layout methods to control the height of elements without explicitly setting a height, and this is a very inflexible approach too — it only works if you can guarantee that your content will be a certain height.

## Flexbox grids?

If you read our previous article about flexbox (ADD LINK) you might think that flexbox is the ideal solution for creating a grid system. There are currently any number of flexbox based grid systems available and flexbox can solve many of the issues that we’ve already discovered when creating our grid above.

However, flexbox was never designed as a grid system and poses a new set of challenges when used as one. As a simple example of this, we can take the same example markup we used above and use the following CSS to style the wrapper, row, and col classes:

```
.wrapper {
  width: 90%;
  max-width: 980px;
  margin: 0 auto;
  padding-right: 2.08333333%;
}

.row {
  display: flex;
}

.col {
  margin-left: 2.08333333%;
  margin-bottom: 1em;
  width: 6.25%;
  flex: 1 1 auto;
  background: rgb(255,150,150);
}
```

You can try making these replacements in your own example, or look at our flexbox-grid.html example code (see it running live also).

Here we are turning each row into a flex container. With a flexbox-based grid we still need rows in order to allow us to have elements that add up to less than 100%. We set that container to `display: flex`.

On `.col` we set the flex property setting `flex-grow` to 1 so our items can grow, `flex-shrink` to 1 so the items can shrink and then set flex-basis to `auto`. As our element has a width set, `auto` will use that width as the flex-basis value.

On the top line we get twelve neat boxes on the grid and they grow and shrink equally as we change the viewport width. On the next line however we only have four items and these also grow and shrink from that 60px basis. With only four of them though they can grow a lot more than the items in the row above, and they don’t respect the grid used by the items above because they don’t know anything about it.

To fix this we still need to include our span classes. As these have a width they will replace the value used by `flex-basis` for that element.

// fig2

 

Flexbox is **one-dimensional** by design. It deals with a single dimension, that of a row or a column. We can’t create a strict grid for columns and rows, meaning that if we were to use flexbox for our grid we still need to calculate percentages as for the floated layout.

In your project you might still choose to use a flexbox ‘grid’ due to the additional alignment and space distribution capabilities flexbox provides over floats. You should however be aware that you are still using a tool for something other than what it was designed for. So you may feel it is making you jump through additional hoops to get the end result you need.

## Third party grid systems

Now that we understand the math behind our grid calculations, we are in a good place to look at some of the third party grid systems in common use. If you search for "CSS Grid framework" on the Web you will find a huge list of options to choose from. Popular frameworks such as Bootstrap and Foundation include a grid system. There are also standalone grid systems, either developed using CSS or using preprocessors.

I’m going to take a look at one of these standalone systems as it demonstrates common techniques for working with a grid framework. The grid I will be using is Skeleton.

1. To get started download Skeleton from [https://getskeleton.com/](https://getskeleton.com/), and unzip the ZIP file. Copy the skeleton.css and normalize.css files into a new directory.

2. Make a copy of our html-skeleton.html file and save it in the same directory as the skeleton and normalize CSS.

3. Include the skeleton and normalize CSS in the HTML page, by adding the following to its head:

<link href="normalize.css" rel="stylesheet">
<link href="skeleton.css" rel="stylesheet">

Skeleton includes more than a grid system — it also contains CSS for typography and other page elements that you can use as a starting point. We’ll leave these at the defaults for now however, it’s the grid we are really interested in here.

Note: normalize is a really useful little CSS library written by Nicolas Gallagher, which automatically does some useful basic layout fixes and makes default element styling more consistent across browsers.

4. We will use similar HTML to our earlier example. Add the following into your HTML body:

<div class="container">
  <div class="row">
    <div class="col">1</div>
    <div class="col">2</div>
    <div class="col">3</div>
    <div class="col">4</div>
    <div class="col">5</div>
    <div class="col">6</div>
    <div class="col">7</div>
    <div class="col">8</div>
    <div class="col">9</div>
    <div class="col">10</div>
    <div class="col">11</div>
    <div class="col">12</div>
  </div>
  <div class="row">
    <div class="col">13</div>
    <div class="col">14</div>
    <div class="col">15</div>
    <div class="col">16</div>   
  </div>
</div>


To start using Skeleton we need to give the wrapper div a class of “container” — this is already included in our HTML. This centers the content with a maximum width of 960 pixels. You can see how the boxes now never become wider than 960 pixels.

You can take a look in the skeleton.css file to see the CSS that is used when we apply this class. The div is centred using auto left and right margins, and a padding of 20 pixels is applied left and right. Skeleton also sets the box-sizing property to border-box so the padding and borders of this element will be included in the total width.

```
    .container {
      position: relative;
      width: 100%;
      max-width: 960px;
      margin: 0 auto;
      padding: 0 20px;
      box-sizing: border-box; }
```

Elements can only be part of the grid if they are inside a row, so as with our earlier example we need an additional div or other element with a class of “row” between the container and our actual content container divs. We've done this already as well.

5. Now let's lay out the container boxes. Skeleton is based on a 12 column grid. The top line boxes all need classes of `one column` to make them span one column.

Add these now, as shown in the following snippet:

```
    <div class="container">
      <div class="row">
        <div class="col one column">1</div>
        <div class="col one column">2</div>        
        <div class="col one column">3</div>
        /* and so on */
      </div>
    </div>
```

6. Next, give the containers on the second row classes explaining the number of columns they should span, like so:

```
    <div class="row">
      <div class="col one column">13</div>
      <div class="col six columns">14</div>
      <div class="col three columns">15</div>
      <div class="col two columns">16</div>   
    </div>
```

If you look in the skeleton.css file you can see how this works. For example, Skeleton has the following defined to style elements with “three columns” classes added to them.

    `.three.columns { width: 22%; }`

All Skeleton (or any other grid framework), is doing is setting up predefined classes that you can use by adding them to your markup. It’s exactly the same as if you did the work of calculating these percentages yourself.

As you can see, we need to write very little CSS when using Skeleton. It deals with all of the floating for us when we add classes to our markup. It is this ability to hand responsibility for layout over to something else that makes using a framework for a grid system a compelling choice!

Skeleton is a simpler grid system than some of the frameworks you may come across. The grids in large frameworks such as Bootstrap and Foundation offer more functionality and additional breakpoints for various screen widths. However they all work in a similar way, by adding classes to your markup you can control how the element lays out using the predefined grid.

## Native CSS Grids with Grid Layout

I said at the beginning of this article that CSS has not previously had a real system for creating grid layouts, but this is set to change. While we can’t use a native CSS grid system yet, in the coming year we should see browser support for the CSS Grid Layout Module [ADD LINK, AND TALK ABOUT BROWSER SUPPORT A BIT MORE; ADD IN HOW TO TURN ON THE FLAG IN SUPPORTING BROWSERS].

Currently you can only use the technique I’ll be showing you in browsers that are implementing CSS Grid Layout “behind a flag” - meaning they are currently in an experimental state that you need to switch on to use.

In Firefox, for example, you need to navigate to a URL of about:config, search for the layout.css.grid.enabled preference, and double click it to enable CSS Grids.

Find out more about the browser status of Grid at https://gridbyexample.com/browsers.

We looked at the Skeleton Grid above — like other third party Grids and even hand built grids, it requires that you add divs to form rows, and then specify the number of columns the items in these rows will span.  

With CSS Grid Layout you can specify your grid entirely in CSS, without needing to add these helper classes to the markup at all. Let’s take our simple example and see how we would create that same layout using CSS Grid Layout.

1. First, get started by making a local copy of the css-grid.html file. It contains the following markup:

```
    <div class="wrapper">
        <div class="col">1</div>
        <div class="col">2</div>
        <div class="col">3</div>
        <div class="col">4</div>
        <div class="col">5</div>
        <div class="col">6</div>
        <div class="col">7</div>
        <div class="col">8</div>
        <div class="col">9</div>
        <div class="col">10</div>
        <div class="col">11</div>
        <div class="col">12</div>
        <div class="col">13</div>
        <div class="col span6">14</div>
        <div class="col span3">15</div>
        <div class="col span2">16</div>       
    </div>
```

This time we have a parent div with a class of wrapper and then all of the child elements just directly inside the wrapper - no row elements. I have added a class to the items that should span more than one column.

2. Now add the following into the {{htmlelement("style")}} element:

.wrapper {
  width: 90%;
  max-width: 960px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-gap: 20px;
}

.col {
  background: rgb(255,150,150);
}

Here we set the .wrapper div so it is 90% of the body width, centered, and has a max-width of 960px.

Now for the CSS grid properites. We can declare a grid using the grid value of the display property, set up a gutter with the grid-gap property and then create a grid of 12 equal width columns using a new unit defined for grid layout - the `fr` unit.

The fr unit is a fraction unit — it describes a fraction of the available space in the grid container. If all tracks are 1fr, they will each take up an equal amount of space. This removes the need to figure out percentages to create a flexible grid.

Having created a grid, the grid auto-placement rules will immediately lay out our boxes on this grid and we get a twelve column flexible grid layout.

// image

To style the containers that span multiple column tracks on the grid we can use the grid-column property. To span 6 columns:

```
.span6 {
  grid-column: auto / span 6;
}

To span 3:

.span3 {
  grid-column: auto / span 3;
}
```

The value before the forward slash is the start line - in this case we are not explicitly setting that and allowing the browser to place the item on the next available line. We can then set it to span 6, 3 or however many lines we want.

3. Add the following at the bottom of your CSS:

.span2 { grid-column: auto / span 2;}
.span3 { grid-column: auto / span 3;}
.span4 { grid-column: auto / span 4;}
.span5 { grid-column: auto / span 5;}
.span6 { grid-column: auto / span 6;}
.span7 { grid-column: auto / span 7;}
.span8 { grid-column: auto / span 8;}
.span9 { grid-column: auto / span 9;}
.span10 { grid-column: auto / span 10;}
.span11 { grid-column: auto / span 11;}
.span12 { grid-column: auto / span 12;}

Try saving and refreshing, and you'll see that the containers span multiple columns as appropriate. Cool!

CSS grids are **two-dimensional**, so as the layout grows and shrinks the elements remain lined up horizontally and vertically.

4. You can test this by replacing your last 4 col divs with the following:

<div class="col">13some<br>content</div>
<div class="col span6">14this<br>is<br>more<br>content</div>
<div class="col span3">15this<br>is<br>less</div>
<div class="col span2">16</div>

Here we've deliberately added in some line break ({{htmlelement("br")}}) tags to force some of the columns to become taller than others. If you try saving and refreshing, you'll see that the columns adjust their height to be as tall as the tallest container, so everything stays neat and tidy.

Note: If you are having trouble getting this example to work, you can check your code against our finished version (also see it running live).

Other nice CSS grid features

With CSS grids, we don’t need to push things along by way of margins to offset them. Trying making these changes in your CSS


.content {
  grid-column: 2 / 8;
}

<div class="col span2 content">16</div>

Container 16 will now span columns 2 to 8, on the next available row where it can fit.

We can span rows just as easily as columns:

```
.content {
   grid-column: 2 / 8;
   grid-row: 3 / 5;
}
```

Container 16 will now span rows 3 to 5, as well as columns 2 to 8.

We also don’t need to calculate the gutter tracks and use a margin to fake gutters as grid has this functionality built right in with the `grid-gap` property.

We’re just touching the surface of what is possible with CSS Grid Layout, but the key thing to understand in the context of this article is that you don’t need to create a grid system with grid - it is one. You can write CSS that places an item directly onto a predefined grid. This is the first time it has been possible with CSS, and this will get a lot more use once browser support solidifies.

 

Summary

 

Having read this article you should now have an understanding of how grid layouts, and grid frameworks work in CSS. You have also had a peek into the future off CSS grids, and should now understand that the grid frameworks we use today are essentially a stopgap solution until we have a widely supported native way of achieving this in CSS.

{{PreviousMenuNext("Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout/Assessment", "Learn/CSS/CSS_layout")}}

Revision Source

<div>{{draft}}{{LearnSidebar}}</div>

<div>{{PreviousMenuNext("Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout/Assessment", "Learn/CSS/CSS_layout")}}</div>

<p class="summary">Grids are an established design tool, and many modern website layouts are based on a regular grid. In this article we’ll take a look at grid-based design, and how CSS can be used to create grids — both with current tools, and new technology that is just starting to become available in browsers.</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Prerequisites:</th>
   <td>HTML basics (study <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML">Introduction to HTML</a>), and an idea of How CSS works (study <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS">Introduction to CSS</a> and <a href="/en-US/docs/Learn/CSS/Styling_boxes">Styling boxes</a>.)</td>
  </tr>
  <tr>
   <th scope="row">Objective:</th>
   <td>To understand the fundamental concepts behind grid layout systems, and how to implement a grid layout on a web page.</td>
  </tr>
 </tbody>
</table>

<h2 id="What_is_grid_layout">What is grid layout?</h2>

<p>A grid is simply a collection of horizontal and vertical lines creating a pattern against which we can line up our design elements. They help us to create designs where elements don’t jump around or change width as we move from page to page, providing greater consistency on our websites.</p>

<p>A grid will typically have <strong>columns</strong>, <strong>rows</strong>, and then gaps between each row and column — often referred to as <strong>gutters</strong>.</p>

<p>[PROVIDE A DIAGRAM DETAILING THE MAIN ELEMENTS OF A GRID SYSTEM]</p>

<p>[Temporary diagram; will be replaced by a better diagram soon.]</p>

<div class="note">
<p><strong>Note</strong>: It may seem surprising to anyone coming from a design background that CSS doesn’t have an inbuilt grid system, and instead we seem to be using a variety of suboptimal methods to create grid-like designs. As you’ll discover in the last part of this article this is set to change, however you are likely to need to know the existing methods of creating grids for some time to come.</p>
</div>

<h2 id="Using_a_“grid_system”_in_your_projects">Using a “grid system” in your projects</h2>

<p>In order to ensure a consistent experience across your site or application, basing it upon a grid system from the outset means you don’t need to think about how wide a certain element is in relation to the other elements. Your choice is limited to “how many columns of the grid this element will span”.</p>

<p>Your “grid system” could simply be a decision made in the design process to use a regular grid. If your designs start life in an application such as Photoshop you can create a grid to reference during that process as described in&nbsp;<a href="https://www.elliotjaystocks.com/blog/a-better-photoshop-grid-for-responsive-web-design/">A better Photoshop grid for responsive web design</a> by Elliot Jay Stocks.</p>

<p>Your grid system may also be a framework — either third party or created by you just for your project — that you use to enforce the grid via CSS.</p>

<h2 id="Creating_simple_grid_frameworks">Creating simple grid frameworks</h2>

<p>We will start by having a look at how you might create a simple grid framework for your project.</p>

<p>At the present time the majority of grid type layouts are created using floats. If you have read <a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">our previous article about floats</a> you’ve already seen how we can use this technique to create a multiple column layout — which is the essence of any grid system using this method.</p>

<p>The easiest type of grid framework to create is a fixed width one — we just need to work out how much total width we want our design to be, how many columns we want, and how wide the gutters and columns should be. If we instead decided to lay out our design on a grid with columns that grow and shrink according to browser width we would need to calculate percentage widths for the columns and&nbsp; gutters between them.</p>

<p>In the next sections we will look at how to create both. We will create a 12 column grid — a very common choice that is seen to be very adaptable to different situations given that 12 is nicely divisible by 6, 4, 3, and 2.</p>

<h3 id="A_simple_fixed_width_grid">A simple fixed width grid</h3>

<p>Lets first create a grid system that uses fixed width columns.</p>

<p>1. Start out by making a local copy of our sample <a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/grids/simple-grid.html">simple-grid.html</a> file, which contains the following markup in its body.</p>

<pre class="brush: html">
&lt;div class="wrapper"&gt;
  &lt;div class="row"&gt;
    &lt;div class="col"&gt;1&lt;/div&gt;
    &lt;div class="col"&gt;2&lt;/div&gt;
    &lt;div class="col"&gt;3&lt;/div&gt;
    &lt;div class="col"&gt;4&lt;/div&gt;
    &lt;div class="col"&gt;5&lt;/div&gt;
    &lt;div class="col"&gt;6&lt;/div&gt;
    &lt;div class="col"&gt;7&lt;/div&gt;
    &lt;div class="col"&gt;8&lt;/div&gt;
    &lt;div class="col"&gt;9&lt;/div&gt;
    &lt;div class="col"&gt;10&lt;/div&gt;
    &lt;div class="col"&gt;11&lt;/div&gt;
    &lt;div class="col"&gt;12&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="row"&gt;
    &lt;div class="col span1"&gt;13&lt;/div&gt;
    &lt;div class="col span6"&gt;14&lt;/div&gt;
    &lt;div class="col span3"&gt;15&lt;/div&gt;
    &lt;div class="col span2"&gt;16&lt;/div&gt;    
  &lt;/div&gt;
&lt;/div&gt;</pre>

<p>The aim is to turn this into a demonstration grid of two rows on a twelve column grid — the top row demonstrating the size of the individual columns, the second row some different sized areas on the grid.</p>

<p>[INSERT IMAGE OF FINISHED EXAMPLE]</p>

<p>2. In the {{htmlelement("style")}} element, add the following code, which first makes all the elements on the page <a href="/en-US/docs/Learn/CSS/Styling_boxes/Box_model_recap#Changing_the_box_model_completely">sized as border boxes</a> and then gives the wrapper container a width of 980 pixels, with padding on the right hand side of 20 pixels. This leaves us with 960 pixels for our total column/gutter widths.</p>

<pre>
* { box-sizing: border-box; }
    
.wrapper {
  width: 980px;
  margin: 0 auto;
  padding-right: 20px;
}</pre>

<p>3. Now use the row container that is wrapped around each row of the grid to clear one row from another. Add the following rule below your previous one:</p>

<p>```<br />
 &nbsp;&nbsp;&nbsp; .row {<br />
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clear: both;<br />
 &nbsp;&nbsp;&nbsp; }<br />
 ```</p>

<p>This clearing means that we don’t need to completely fill each row with elements making the full twelve columns. The rows will remaining separated, and not interfere with each other.</p>

<p>The gutters between the columns are 20 pixels wide. We create these gutters as a margin on the left side of each column - including the first column. This will then balance out the 20 pixels of padding on the right side of the container. So we have 12 gutters in total - 12 x 20 = 240.</p>

<p>We need to subtract that from our total width of 960 pixels, giving us 720 pixels for our columns. If we now divide that by 12, we know that each column should be 60 pixels wide.</p>

<p>4. Our next step is to create rules for the class ‘.col’,&nbsp; floating it left, giving it a margin-left of 20 pixels to form the gutter, and a width of 60px. The top row of single columns will now lay out neatly as a grid.</p>

<p>Note: We've also given each column a light red color so you can see exactly how much space each one takes up.</p>

<p>Add the following rule to the bottom of your CSS:</p>

<p>.col {<br />
 &nbsp; float: left;<br />
 &nbsp; margin-left: 20px;<br />
 &nbsp; width: 60px;<br />
 &nbsp; background: rgb(255,150,150);<br />
 }</p>

<p>5. To enable layout containers that span more than one column, we will need to create some additional classes to allow them to span 2 to 12 columns. We do this by adding up the column width of that number of columns plus the gutter widths.</p>

<p>Add the following at the bottom of your CSS:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;/* Two column widths (120px) plus one gutter width (20px) */<br />
 &nbsp; .col.span2 { width: 140px; }<br />
 &nbsp; /* Three column widths (180px) plus two gutter widths (40px) */<br />
 &nbsp;&nbsp; &nbsp;.col.span3 { width: 220px; }<br />
 &nbsp; /* And so on... */<br />
 &nbsp;&nbsp; &nbsp;.col.span4 { width: 300px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span5 { width: 380px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span6 { width: 460px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span7 { width: 540px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span8 { width: 620px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span9 { width: 700px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span10 { width: 780px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span11 { width: 860px; }<br />
 &nbsp;&nbsp; &nbsp;.col.span12 { width: 940px; }<br />
 ```</p>

<p>6. With these classes created we can now lay out different width columns on my grid. Try saving and loading the page in your browser to see the effects.</p>

<p>Note: If you are having trouble getting the above example to work, try comparing it against our finished version on GitHub (see it running live also).</p>

<p>7. Try modifying the classes on your elements and even adding and removing some containers, to see how you can vary the layout. For example, you could make the second row look like this:</p>

<p>```<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="row"&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col span8"&gt;13&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col span4"&gt;14&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp; &lt;/div&gt;<br />
 ```</p>

<p>Now you've got a grid system working, you can simply define the rows and the number of columns in each row, then fill each container with your required content.</p>

<p>### Creating a fluid grid</p>

<p>Our grid works nicely, but it is fixed width. We really want a flexible (fluid) grid that will grow and shrink with the available space in the browser viewport. To achieve this we can use the reference pixel widths and turn them into percentages.</p>

<p>The equation that turns a fixed width into a flexible percentage-based one is as follows.</p>

<p>target / context = result</p>

<p>For our column width, our _target width_ is **60 pixels** and our _context_ is the **960 pixel** wrapper. We can use the following to calculate a percentage.</p>

<p>60 / 960 = 0.0625</p>

<p>We then move the decimal point 2 places, giving us a percentage of 6.25%. In our CSS we can replace 60 pixels with 6.25%.</p>

<p>We need to do the same with our margin.</p>

<p>20 / 960 = 0.02083333333</p>

<p>So we need to replace the 20 pixel marign-left on our .col rule, and the right hand padding on .wrapper, with 2.08333333%.</p>

<p>1. To get started in this section, make a new copy of your previous example page, or use our simple-grid-finished.html code as a starting point.</p>

<p>2. Replace the second CSS rule (with the .wrapper selector) as follows:</p>

<p>.wrapper {<br />
 &nbsp; width: 90%;<br />
 &nbsp; max-width: 980px;<br />
 &nbsp; margin: 0 auto;<br />
 &nbsp; padding-right: 2.08333333%;<br />
 }</p>

<p>Not only have we given it a width as a percentage, we have&nbsp; also added a `max-width` property in order to stop the layout becoming too wide.</p>

<p>3. Next, replace the fourth CSS rule (with the .col selector) like so:</p>

<p>.col {<br />
 &nbsp; float: left;<br />
 &nbsp; margin-left: 2.08333333%;<br />
 &nbsp; width: 6.25%;<br />
 &nbsp; background: rgb(255,150,150);<br />
 }</p>

<p>4. Now comes the slightly more laborious part — we need to update all our .col.span rules to use percentages rather than pixel widths. This takes a bit of time with a calculator; to save you some effort, we've done it for you below.</p>

<p>Update the bottom block of CSS rules with the following:</p>

<p>/* Two column widths (12.5%) plus one gutter width (2.08333333%) */<br />
 .col.span2 { width: 14.58333333%; }<br />
 /* Three column widths (18.75%) plus two gutter widths (4.1666666) */<br />
 .col.span3 { width: 22.91666666%; }<br />
 /* And so on... */<br />
 .col.span4 { width: 31.24999999%; }<br />
 .col.span5 { width: 39.58333332%; }<br />
 .col.span6 { width: 47.91666665%; }<br />
 .col.span7 { width: 56.24999998%; }<br />
 .col.span8 { width: 64.58333331%; }<br />
 .col.span9 { width: 72.91666664%; }<br />
 .col.span10 { width: 81.24999997%; }<br />
 .col.span11 { width: 89.5833333%; }<br />
 .col.span12 { width: 97.91666663%; }</p>

<p>5. Save your code, load it in a browser, and try changing the viewport width —&nbsp;you should see the column widths adjust nicely to suit. Great!</p>

<p>Note: If you are having trouble getting the above example to work, try comparing it against our finished version on GitHub (see it running live also).</p>

<p>Easier calculations using the calc() function</p>

<p>You could use the `calc()` function to do the math right inside your CSS. Let’s have a look at how calc() works. (CHECK TO SEE IF I'VE COVERED THIS ANYWHERE ELSE ALREADY)</p>

<p>Any column that spans more than one column of our grid is a total width of 6.25 multiplied by the number of columns spanned plus 2.08333333 multiplied by the number of gutters (which will always be the number of columns minus 1). The calc function means we can do this as the value of width, so for anY item spanning 4 columns we can do this, for example:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;.col.span4 {<br />
 &nbsp;&nbsp; &nbsp;&nbsp; width: calc((6.25%*4) + (2.08333333%*3));<br />
 &nbsp;&nbsp; &nbsp;}<br />
 ```</p>

<p>Try replacing your bottom block of rules with the following, then reload it in the browser to see if you get the same result:</p>

<p>.col.span2 { width: calc((6.25%*2) + 2.08333333%); }<br />
 .col.span3 { width: calc((6.25%*3) + (2.08333333%*2)); }<br />
 .col.span4 { width: calc((6.25%*4) + (2.08333333%*3)); }<br />
 .col.span5 { width: calc((6.25%*5) + (2.08333333%*4)); }<br />
 .col.span6 { width: calc((6.25%*6) + (2.08333333%*5)); }<br />
 .col.span7 { width: calc((6.25%*7) + (2.08333333%*6)); }<br />
 .col.span8 { width: calc((6.25%*8) + (2.08333333%*7)); }<br />
 .col.span9 { width: calc((6.25%*9) + (2.08333333%*8)); }<br />
 .col.span10 { width: calc((6.25%*10) + (2.08333333%*9)); }<br />
 .col.span11 { width: calc((6.25%*11) + (2.08333333%*10)); }<br />
 .col.span12 { width: calc((6.25%*12) + (2.08333333%*11)); }</p>

<p>Note: You can see our version in fluid-grid-calc.html (also see it live).</p>

<p>Note: If you can't get this to work, it might be because your browser does not support the calc() function — it is a fairly recent addition to browsers, which works in [ADD BROWSER SUPPORT STATS]</p>

<p>### Semantic versus “un-semantic” grid systems</p>

<p>Adding classes to your markup to define layout does mean that your content and markup becomes tied to the visual presentation. You will sometimes hear this use of CSS classes described as being “un-semantic”, rather than a semantic use of classes that describes the content rather than how the content looks.</p>

<p>You do not need to add the span2, span3 etc. classes to your markup. You could instead decide on your grid and then add the sizing information to the rules for existing - semantic - classes. For example, I have a div with a class of content that I want to span 8 columns and so I copy across the width from the `span8` class:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;.content {<br />
 &nbsp;&nbsp; &nbsp;&nbsp; width: calc((6.25%*8) + (2.08333333%*7));<br />
 &nbsp;&nbsp; &nbsp;}<br />
 ```</p>

<p>If you use a preprocessor such as Sass then you could create a simple mixin to insert that value for you.</p>

<p>### Limitations of our grid</p>

<p>The grid we have created works well as long as we want to start all of the rows flush with the left hand side of the grid. If we wanted to leave a gap before the first item we would need to create an offset class adding a left margin to our site to push it across the grid visually. More math!</p>

<p>Let's try this out.</p>

<p>1. Start with your previous code, or use our fluid-grid.html file as a starting point.</p>

<p>2.&nbsp; Let's create a class in our CSS that will offset a container element by one column width. Add the following to the bottom of your CSS:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;.offset-by-one {<br />
 &nbsp;&nbsp; &nbsp;&nbsp; margin-left: calc(6.25% + (2.08333333%*2));<br />
 &nbsp;&nbsp; &nbsp;}<br />
 ```</p>

<p>Or if you are prefer to calculate the percentages yourself, use this one:</p>

<p>```<br />
 &nbsp; .offset-by-one {<br />
 &nbsp;&nbsp;&nbsp; margin-left: 10.41666666%;<br />
 &nbsp; }<br />
 ```</p>

<p>3. You can now add this class to any container you want, to leave a one column width gap on the left hand side of it. For example, if you have this in your HTML:</p>

<p>&lt;div class="col span6"&gt;14&lt;/div&gt;</p>

<p>Try replacing it with</p>

<p>&lt;div class="col span5 offset-by-one"&gt;14&lt;/div&gt;</p>

<p>Note: Notice that you need to reduce the number of columns spanned, to make room for the offset!</p>

<p>4. Try loading and refreshing to see the difference, or check out our fluid-grid-offset.html example (see it running live also).</p>

<p>Note: As an extra exercise, can you implement an offset-by-two class?</p>

<p>Floated grid limitations</p>

<p>When using a system like this you do need to take care that your total widths add up correctly, and that you don’t include elements in a row that span more columns than the row cna contain. Due to the way floats work, if your total width becomes wider than 100% the excess items will drop to the next line.</p>

<p>If the content of the elements pushes them to become wider this will also make the total width more than 100% and the same thing will happen.</p>

<p>The container div with a class of row helps to prevent our design falling into chaos should our lines not add up neatly to 100% but you do need to do a fair amount of managing of the grid when using this method. Commonly you would use media queries to create a different layout at narrower breakpoints to ensure that you don’t have the issue of the grid pushing too wide.</p>

<p>An additional limitation of this system is that it is essentially one dimensional. We are dealing with columns, and spanning elements across columns, but not rows. It is very difficult with these older layout methods to control the height of elements without explicitly setting a height, and this is a very inflexible approach too — it only works if you can guarantee that your content will be a certain height.</p>

<p>## Flexbox grids?</p>

<p>If you read our previous article about flexbox (ADD LINK) you might think that flexbox is the ideal solution for creating a grid system. There are currently any number of flexbox based grid systems available and flexbox can solve many of the issues that we’ve already discovered when creating our grid above.</p>

<p>However, flexbox was never designed as a grid system and poses a new set of challenges when used as one. As a simple example of this, we can take the same example markup we used above and use the following CSS to style the wrapper, row, and col classes:</p>

<p>```<br />
 .wrapper {<br />
 &nbsp; width: 90%;<br />
 &nbsp; max-width: 980px;<br />
 &nbsp; margin: 0 auto;<br />
 &nbsp; padding-right: 2.08333333%;<br />
 }</p>

<p>.row {<br />
 &nbsp; display: flex;<br />
 }</p>

<p>.col {<br />
 &nbsp; margin-left: 2.08333333%;<br />
 &nbsp; margin-bottom: 1em;<br />
 &nbsp; width: 6.25%;<br />
 &nbsp; flex: 1 1 auto;<br />
 &nbsp; background: rgb(255,150,150);<br />
 }<br />
 ```</p>

<p>You can try making these replacements in your own example, or look at our flexbox-grid.html example code (see it running live also).</p>

<p>Here we are turning each row into a flex container. With a flexbox-based grid we still need rows in order to allow us to have elements that add up to less than 100%. We set that container to `display: flex`.</p>

<p>On `.col` we set the flex property setting `flex-grow` to 1 so our items can grow, `flex-shrink` to 1 so the items can shrink and then set flex-basis to `auto`. As our element has a width set, `auto` will use that width as the flex-basis value.</p>

<p>On the top line we get twelve neat boxes on the grid and they grow and shrink equally as we change the viewport width. On the next line however we only have four items and these also grow and shrink from that 60px basis. With only four of them though they can grow a lot more than the items in the row above, and they don’t respect the grid used by the items above because they don’t know anything about it.</p>

<p>To fix this we still need to include our span classes. As these have a width they will replace the value used by `flex-basis` for that element.</p>

<p>// fig2</p>

<p>&nbsp;</p>

<p>Flexbox is **one-dimensional** by design. It deals with a single dimension, that of a row or a column. We can’t create a strict grid for columns and rows, meaning that if we were to use flexbox for our grid we still need to calculate percentages as for the floated layout.</p>

<p>In your project you might still choose to use a flexbox ‘grid’ due to the additional alignment and space distribution capabilities flexbox provides over floats. You should however be aware that you are still using a tool for something other than what it was designed for. So you may feel it is making you jump through additional hoops to get the end result you need.</p>

<p>## Third party grid systems</p>

<p>Now that we understand the math behind our grid calculations, we are in a good place to look at some of the third party grid systems in common use. If you search for "CSS Grid framework" on the Web you will find a huge list of options to choose from. Popular frameworks such as Bootstrap and Foundation include a grid system. There are also standalone grid systems, either developed using CSS or using preprocessors.</p>

<p>I’m going to take a look at one of these standalone systems as it demonstrates common techniques for working with a grid framework. The grid I will be using is Skeleton.</p>

<p>1. To get started download Skeleton from [https://getskeleton.com/](https://getskeleton.com/), and unzip the ZIP file. Copy the skeleton.css and normalize.css files into a new directory.</p>

<p>2. Make a copy of our html-skeleton.html file and save it in the same directory as the skeleton and normalize CSS.</p>

<p>3. Include the skeleton and normalize CSS in the HTML page, by adding the following to its head:</p>

<p>&lt;link href="normalize.css" rel="stylesheet"&gt;<br />
 &lt;link href="skeleton.css" rel="stylesheet"&gt;</p>

<p>Skeleton includes more than a grid system — it also contains CSS for typography and other page elements that you can use as a starting point. We’ll leave these at the defaults for now however, it’s the grid we are really interested in here.</p>

<p>Note: normalize is a really useful little CSS library written by Nicolas Gallagher, which automatically does some useful basic layout fixes and makes default element styling more consistent across browsers.</p>

<p>4. We will use similar HTML to our earlier example. Add the following into your HTML body:</p>

<p>&lt;div class="container"&gt;<br />
 &nbsp; &lt;div class="row"&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;1&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;2&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;3&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;4&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;5&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;6&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;7&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;8&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;9&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;10&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;11&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;12&lt;/div&gt;<br />
 &nbsp; &lt;/div&gt;<br />
 &nbsp; &lt;div class="row"&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;13&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;14&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;15&lt;/div&gt;<br />
 &nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;16&lt;/div&gt;&nbsp; &nbsp;<br />
 &nbsp; &lt;/div&gt;<br />
 &lt;/div&gt;</p>

<p><br />
 To start using Skeleton we need to give the wrapper div a class of “container” — this is already included in our HTML. This centers the content with a maximum width of 960 pixels. You can see how the boxes now never become wider than 960 pixels.</p>

<p>You can take a look in the skeleton.css file to see the CSS that is used when we apply this class. The div is centred using auto left and right margins, and a padding of 20 pixels is applied left and right. Skeleton also sets the box-sizing property to border-box so the padding and borders of this element will be included in the total width.</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;.container {<br />
 &nbsp;&nbsp; &nbsp;&nbsp; position: relative;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; width: 100%;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; max-width: 960px;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; margin: 0 auto;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; padding: 0 20px;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; box-sizing: border-box; }<br />
 ```</p>

<p>Elements can only be part of the grid if they are inside a row, so as with our earlier example we need an additional div or other element with a class of “row” between the container and our actual content container divs. We've done this already as well.</p>

<p>5. Now let's lay out the container boxes. Skeleton is based on a 12 column grid. The top line boxes all need classes of `one column` to make them span one column.</p>

<p>Add these now, as shown in the following snippet:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;&lt;div class="container"&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; &lt;div class="row"&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col one column"&gt;1&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col one column"&gt;2&lt;/div&gt;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col one column"&gt;3&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; /* and so on */<br />
 &nbsp;&nbsp; &nbsp;&nbsp; &lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&lt;/div&gt;<br />
 ```</p>

<p>6. Next, give the containers on the second row classes explaining the number of columns they should span, like so:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;&lt;div class="row"&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; &lt;div class="col one column"&gt;13&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; &lt;div class="col six columns"&gt;14&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; &lt;div class="col three columns"&gt;15&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp; &lt;div class="col two columns"&gt;16&lt;/div&gt;&nbsp; &nbsp;<br />
 &nbsp;&nbsp; &nbsp;&lt;/div&gt;<br />
 ```</p>

<p>If you look in the skeleton.css file you can see how this works. For example, Skeleton has the following defined to style elements with “three columns” classes added to them.</p>

<p>&nbsp;&nbsp;&nbsp; `.three.columns { width: 22%; }`</p>

<p>All Skeleton (or any other grid framework), is doing is setting up predefined classes that you can use by adding them to your markup. It’s exactly the same as if you did the work of calculating these percentages yourself.</p>

<p>As you can see, we need to write very little CSS when using Skeleton. It deals with all of the floating for us when we add classes to our markup. It is this ability to hand responsibility for layout over to something else that makes using a framework for a grid system a compelling choice!</p>

<p>Skeleton is a simpler grid system than some of the frameworks you may come across. The grids in large frameworks such as Bootstrap and Foundation offer more functionality and additional breakpoints for various screen widths. However they all work in a similar way, by adding classes to your markup you can control how the element lays out using the predefined grid.</p>

<p>## Native CSS Grids with Grid Layout</p>

<p>I said at the beginning of this article that CSS has not previously had a real system for creating grid layouts, but this is set to change. While we can’t use a native CSS grid system yet, in the coming year we should see browser support for the CSS Grid Layout Module [ADD LINK, AND TALK ABOUT BROWSER SUPPORT A BIT MORE; ADD IN HOW TO TURN ON THE FLAG IN SUPPORTING BROWSERS].</p>

<p>Currently you can only use the technique I’ll be showing you in browsers that are implementing CSS Grid Layout “behind a flag” - meaning they are currently in an experimental state that you need to switch on to use.</p>

<p>In Firefox, for example, you need to navigate to a URL of about:config, search for the layout.css.grid.enabled preference, and double click it to enable CSS Grids.</p>

<p>Find out more about the browser status of Grid at https://gridbyexample.com/browsers.</p>

<p>We looked at the Skeleton Grid above — like other third party Grids and even hand built grids, it requires that you add divs to form rows, and then specify the number of columns the items in these rows will span. &nbsp;</p>

<p>With CSS Grid Layout you can specify your grid entirely in CSS, without needing to add these helper classes to the markup at all. Let’s take our simple example and see how we would create that same layout using CSS Grid Layout.</p>

<p>1. First, get started by making a local copy of the css-grid.html file. It contains the following markup:</p>

<p>```<br />
 &nbsp;&nbsp; &nbsp;&lt;div class="wrapper"&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;1&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;2&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;3&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;4&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;5&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;6&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;7&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;8&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;9&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;10&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;11&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;12&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col"&gt;13&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col span6"&gt;14&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col span3"&gt;15&lt;/div&gt;<br />
 &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;div class="col span2"&gt;16&lt;/div&gt;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />
 &nbsp;&nbsp; &nbsp;&lt;/div&gt;<br />
 ```</p>

<p>This time we have a parent div with a class of wrapper and then all of the child elements just directly inside the wrapper - no row elements. I have added a class to the items that should span more than one column.</p>

<p>2. Now add the following into the {{htmlelement("style")}} element:</p>

<p>.wrapper {<br />
 &nbsp; width: 90%;<br />
 &nbsp; max-width: 960px;<br />
 &nbsp; margin: 0 auto;<br />
 &nbsp; display: grid;<br />
 &nbsp; grid-template-columns: repeat(12, 1fr);<br />
 &nbsp; grid-gap: 20px;<br />
 }</p>

<p>.col {<br />
 &nbsp; background: rgb(255,150,150);<br />
 }</p>

<p>Here we set the .wrapper div so it is 90% of the body width, centered, and has a max-width of 960px.</p>

<p>Now for the CSS grid properites. We can declare a grid using the grid value of the display property, set up a gutter with the grid-gap property and then create a grid of 12 equal width columns using a new unit defined for grid layout - the `fr` unit.</p>

<p>The fr unit is a fraction unit — it describes a fraction of the available space in the grid container. If all tracks are 1fr, they will each take up an equal amount of space. This removes the need to figure out percentages to create a flexible grid.</p>

<p>Having created a grid, the grid auto-placement rules will immediately lay out our boxes on this grid and we get a twelve column flexible grid layout.</p>

<p>// image</p>

<p>To style the containers that span multiple column tracks on the grid we can use the grid-column property. To span 6 columns:</p>

<p>```<br />
 .span6 {<br />
 &nbsp; grid-column: auto / span 6;<br />
 }</p>

<p>To span 3:</p>

<p>.span3 {<br />
 &nbsp; grid-column: auto / span 3;<br />
 }<br />
 ```</p>

<p>The value before the forward slash is the start line - in this case we are not explicitly setting that and allowing the browser to place the item on the next available line. We can then set it to span 6, 3 or however many lines we want.</p>

<p>3. Add the following at the bottom of your CSS:</p>

<p>.span2 { grid-column: auto / span 2;}<br />
 .span3 { grid-column: auto / span 3;}<br />
 .span4 { grid-column: auto / span 4;}<br />
 .span5 { grid-column: auto / span 5;}<br />
 .span6 { grid-column: auto / span 6;}<br />
 .span7 { grid-column: auto / span 7;}<br />
 .span8 { grid-column: auto / span 8;}<br />
 .span9 { grid-column: auto / span 9;}<br />
 .span10 { grid-column: auto / span 10;}<br />
 .span11 { grid-column: auto / span 11;}<br />
 .span12 { grid-column: auto / span 12;}</p>

<p>Try saving and refreshing, and you'll see that the containers span multiple columns as appropriate. Cool!</p>

<p>CSS grids are **two-dimensional**, so as the layout grows and shrinks the elements remain lined up horizontally and vertically.</p>

<p>4. You can test this by replacing your last 4 col divs with the following:</p>

<p>&lt;div class="col"&gt;13some&lt;br&gt;content&lt;/div&gt;<br />
 &lt;div class="col span6"&gt;14this&lt;br&gt;is&lt;br&gt;more&lt;br&gt;content&lt;/div&gt;<br />
 &lt;div class="col span3"&gt;15this&lt;br&gt;is&lt;br&gt;less&lt;/div&gt;<br />
 &lt;div class="col span2"&gt;16&lt;/div&gt;</p>

<p>Here we've deliberately added in some line break ({{htmlelement("br")}}) tags to force some of the columns to become taller than others. If you try saving and refreshing, you'll see that the columns adjust their height to be as tall as the tallest container, so everything stays neat and tidy.</p>

<p>Note: If you are having trouble getting this example to work, you can check your code against our finished version (also see it running live).</p>

<p>Other nice CSS grid features</p>

<p>With CSS grids, we don’t need to push things along by way of margins to offset them. Trying making these changes in your CSS</p>

<p><br />
 .content {<br />
 &nbsp; grid-column: 2 / 8;<br />
 }</p>

<p>&lt;div class="col span2 content"&gt;16&lt;/div&gt;</p>

<p>Container 16 will now span columns 2 to 8, on the next available row where it can fit.</p>

<p>We can span rows just as easily as columns:</p>

<p>```<br />
 .content {<br />
 &nbsp;&nbsp; grid-column: 2 / 8;<br />
 &nbsp;&nbsp; grid-row: 3 / 5;<br />
 }<br />
 ```</p>

<p>Container 16 will now span rows 3 to 5, as well as columns 2 to 8.</p>

<p>We also don’t need to calculate the gutter tracks and use a margin to fake gutters as grid has this functionality built right in with the `grid-gap` property.</p>

<p>We’re just touching the surface of what is possible with CSS Grid Layout, but the key thing to understand in the context of this article is that you don’t need to create a grid system with grid - it is one. You can write CSS that places an item directly onto a predefined grid. This is the first time it has been possible with CSS, and this will get a lot more use once browser support solidifies.</p>

<p>&nbsp;</p>

<h2 id="Summary">Summary</h2>

<p>&nbsp;</p>

<p>Having read this article you should now have an understanding of how grid layouts, and grid frameworks work in CSS. You have also had a peek into the future off CSS grids, and should now understand that the grid frameworks we use today are essentially a stopgap solution until we have a widely supported native way of achieving this in CSS.</p>

<p>{{PreviousMenuNext("Learn/CSS/CSS_layout/Flexbox", "Learn/CSS/CSS_layout/Assessment", "Learn/CSS/CSS_layout")}}</p>
Revert to this revision