How to build a Grid-based framework using the float property
Published: 2020-01-29 20:41:24

{% github fivan18/grid-based-framework %}

As part of the fast track program at [Microverse](https://www.microverse.org/) I started to learn HTML and CSS by cloning some pages. There was a project I learned about positioning and floating elements, it was no easy but approachable. In the subsequent projects, I decided to use the floating technique to position elements because that way I got a strong foundation of float property.

The grid-based framework was one of those HTML and CSS's projects, it was actually the last one of this course. 

Well, I know that there are different techniques to position elements nowadays like Flexbox but I struggled the most using `float` property, that's why I decided to use it to build this project. 

## How to build the grid-based framework

To figure out how to build the framework it was easier to use it in one of the projects that I worked with. So I chose the [TNW clone](https://github.com/fivan18/tnw-clone). It gave me the guideline.

The next step was to refresh my knowledge about float and grids. These were the articles on which I relied:

- [All About Floats](https://css-tricks.com/all-about-floats/) by Chris Coyer

- [Don't Overthink It Grids](https://css-tricks.com/dont-overthink-it-grids/) by Chris Coyer

- [Fluid Grids](https://alistapart.com/article/fluidgrids/) by Ethan Marcotte

### Sections to be built with the framework

The [TNW page](https://thenextweb.com/) has 5 sections with a similar behavior: each contains similar items that resize accordingly with the viewport (fluid grid) and expand in different proportions when the viewport reaches out a specific size (responsive design). Let's give it an example:

The [Latest news](https://thenextweb.com/latest/) section has 8 similar items.

![Latest News](https://thepracticaldev.s3.amazonaws.com/i/epq97vad03tfmtjp7rau.png)

When we resize the viewport, the size of each item will change according to it.

![Latest News Resize](https://thepracticaldev.s3.amazonaws.com/i/wrbtflimlpj7im05jdj5.png)


If we reach out 1024 pixels (breakpoint), instead of four items per row it'll be 3 items per row (they expand in different proportions).

![Latest News Breakpoint](https://thepracticaldev.s3.amazonaws.com/i/tpupuce5qgvroe1qishf.png)

Having all those things in mind I started to build the framework that fits my requirements. I thought about [Bootstrap's Grid System](https://getbootstrap.com/docs/4.4/layout/grid/) and how easy it could be to clone the page using it. So, I decided to build a Bootstrap-like grid framework. 

### Basic grid-based framework

Look at the code below and try to understand it. It illustrates the use of the grid-based framework. You can change the viewport size by clicking on the buttons that are at the bottom middle of the CodePen tool. The ones that have the next labels: 1x, 0.5x and 0.25x.

{% codepen https://codepen.io/fivan/pen/VwYVQXV default-tab=result %}

As I said, it's a Bootstrap-like framework. It uses rows and columns to layout and aligns content. The main classes to layout the grid are `row` and `col-{breakpoint}-{number of columns}`. Where:

`{breakpoint}`: it's a number that represents the breakpoint in pixels. Grid breakpoints are based on minimum width media queries, meaning they apply to that one breakpoint and all those above it.

`{number of columns}`: indicates the number of columns you’d like to use out of the possible 12 per row. 

#### HTML layout

As you saw, the example is basically a grid layout with six items:

```
<div class="row well">
  <div class="col-0-12 col-576-6 col-720-4 col-1024-3 col-1200-2">
    <div class="well h"></div>
  </div>
  <div class="col-0-12 col-576-6 col-720-4 col-1024-3 col-1200-2">
    <div class="well h"></div>
  </div>
  <div class="col-0-12 col-576-6 col-720-4 col-1024-3 col-1200-2">
    <div class="well h"></div>
  </div>
  <div class="col-0-12 col-576-6 col-720-4 col-1024-3 col-1200-2">
    <div class="well h"></div>
  </div>
  <div class="col-0-12 col-576-6 col-720-4 col-1024-3 col-1200-2">
    <div class="well h"></div>
  </div>
  <div class="col-0-12 col-576-6 col-720-4 col-1024-3 col-1200-2">
    <div class="well h"></div>
  </div>
</div>

```

Let me explain a little bit about how the classes work in this case:

- `row`: container of the columns. It is necessary to enclose the columns in a container with this class, I'll explain why later on in the article.
- `col-0-12`: the item will take 12 columns by default unless another column class is used.
- `col-576-6`: the item will take 6 columns when the viewport reaches out 576px and all the breakpoints above it unless another column class with a greater breakpoint is used.
- `col-720-4`: the item will take 4 columns when the viewport reaches out 720px and all the breakpoints above it unless another column class with a greater breakpoint is used.
- `col-1024-3`: the item will take 3 columns when the viewport reaches out 1024px and all the breakpoints above it unless another column class with a greater breakpoint is used.
- `col-1200-2`: the item will take 2 columns when the viewport reaches out 1200px and all the breakpoints above it unless another column class with a greater breakpoint is used.

#### CSS stylesheet

`.row` is basically the container of the items. Due it has nothing but floated elements, the height of it literally collapses to nothing. You can read a really good explanation [here](https://css-tricks.com/all-about-floats/#article-header-id-3). So, we use the [Easy Clearing Method](https://css-tricks.com/all-about-floats/#article-header-id-4) to deal with this situation.

```
.row::after {
    content: ".";
    visibility: hidden;
    display: block;
    height: 0;
    clear: both;
}
```

`.col-{breakpoints}-{number of columns}` rule has nothing more than the `float: left` and `width: XX.XX%` properties setting in its body. That way we get a fluid-grid behavior.

```
  .col-XXXX-1 {
    float: left;
    width: 8.33%;
  }
  
  .col-XXXX-2 {
    float: left;
    width: 16.66%;
  }
  
  .col-XXXX-3 {
    float: left;
    width: 25%;
  }
  
  .col-XXXX-4 {
    float: left;
    width: 33.33%;
  }
  
  .col-XXXX-5 {
    float: left;
    width: 41.66%;
  }
  
  .col-XXXX-6 {
    float: left;
    width: 50%;
  }
  
  .col-XXXX-7 {
    float: left;
    width: 58.33%;
  }
  
  .col-XXXX-8 {
    float: left;
    width: 66.66%;
  }
  
  .col-XXXX-9 {
    float: left;
    width: 75%;
  }
  
  .col-XXXX-10 {
    float: left;
    width: 83.33%;
  }
  
  .col-XXXX-11 {
    float: left;
    width: 91.66%;
  }
  
  .col-XXXX-12 {
    float: left;
    width: 100%;
  }
```
To make the grid responsive we only need to put the code above inside a media query, replacing `XXXX` with the corresponding breakpoint. For example:
```
@media screen and (min-width: 576px) {
    .col-576-1 {
      float: left;
      width: 8.33%;
    }
  
    .col-576-2 {
      float: left;
      width: 16.66%;
    }
  
    .col-576-3 {
      float: left;
      width: 25%;
    }
  
    .col-576-4 {
      float: left;
      width: 33.33%;
    }
  
    .col-576-5 {
      float: left;
      width: 41.66%;
    }
  
    .col-576-6 {
      float: left;
      width: 50%;
    }
  
    .col-576-7 {
      float: left;
      width: 58.33%;
    }
  
    .col-576-8 {
      float: left;
      width: 66.66%;
    }
  
    .col-576-9 {
      float: left;
      width: 75%;
    }
  
    .col-576-10 {
      float: left;
      width: 83.33%;
    }
  
    .col-576-11 {
      float: left;
      width: 91.66%;
    }
  
    .col-576-12 {
      float: left;
      width: 100%;
    }
    
}
```

### Adding gutters

I used `padding` and `box-sizing` properties to add the gutters. Let's take a look at the next example, it's almost the same as the example above with some rules added in the stylesheet.


{% codepen https://codepen.io/fivan/pen/xxbNXEN default-tab=result %}

#### Stylesheet

The items (`col-{breakpoints}-{number of columns}`) and its container (`row`) need to include the `padding` size in their width. We achieve this by using the next CSS rule:

```
* {
  box-sizing: border-box;
}
```

The next step is to set the `padding-right` and `padding-top` properties in each of the grid items.

```
[class*="col-"] {
  padding-right: 20px;
  padding-top: 20px;
}
```
Finally, to include the gutters that are missing on the left and bottom of the container we set the corresponding `padding` properties to it.

```
.row {
  padding-left: 20px;
  padding-bottom: 20px;
}
```

And, that's it.

### Conclusion

Well, this is a basic explanation to build a grid-based framework using the `float` property. It helped a lot to understand this technique to position elements. 

In the example that I illustrated, the items in the grid have the same `height` value and it works really well. But, what if we have different values for each item? Yes, there is a problem when it happens. There is a peculiar behavior with the floating elements that cause the grid layout breaks. I'll explain it in another article and the way how I solved it.


To be continued...