Dropping CSS frameworks for Grid and Flexbox
Tags: css, html, grid, flexbox
Published: 2018-09-17 05:14:16

---
title: Dropping CSS frameworks for Grid and Flexbox
published: true
tags: css,html,grid,flexbox
canonical_url: https://www.angelolakra.com/articles/building-out-new-sites-with-css-grid-and-flexbox/
---

 ![Dropping CSS frameworks for Grid and Flexbox](https://images.unsplash.com/photo-1504454449875-92cfa39e1315?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=6561d4b681332e316e7f21a6228ad9c8)

**I was developing in a world full of CSS hacks going back from 2000 to 2010**. I was used to floating, inline-blocking and clearfixes to manage layout. I had tried to learn to use flexbox a few years ago, but it was when it was first introduced and most of the properties were browser-prefixed and didn't always work consistently. So I just gave up and put down front-end development down for a while I waited for things to mature.

**I avoided the pain by subscribing to the camps that used things like [Bootstrap](http://getbootstrap.com/), [Foundation](https://foundation.zurb.com/) and [Skeleton](http://getskeleton.com/)**. These were safe harbors where I could build applications quickly and focus on providing solid backends.

**My interest was sparked again when I walked over to my coworker and asked him what he was working on**. He showed me two tutorials of CSS [grid](https://css-tricks.com/snippets/css/complete-guide-grid/) and [flex](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) and gave me a quick proof-of-concept of what they both could do together and I was blown away.

**I decided to build a page without a CSS framework only using grid and flexbox**. I have to say that I am very pleased with how straightforward and simple it was to make a functional layout without worrying too much about the structure of my HTML.

## What does a CSS grid and flexbox workflow for a fixed-width layout look like?

Here's the `HTML`:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Test Grid Layouts</title>
    <link rel="stylesheet" href="styles.css">
  </head>

  <body>
    <div class="container">
      <header>
        <nav>
          <div id="logo">Using Grid</div>
          <ul>
            <li><a href="#">About</a></li>
            <li><a href="#">Blog</a></li>
            <li><a href="#">Contact</a></li>
          </ul>
        </nav>
      </header>

      <main>
        <div class="content">
          <section class="hero">
            <h3>Color Me Black</h3>
          </section>

          <article>
            <h1>Title</h1>
            <p>I love content!</p>
          </article>
        </div>
      </main>

      <footer>
        <nav>
          <div class="siteinfo">Made by Angelo</div>
        </nav>
      </footer>
    </div>
  </body>
</html>
```

And the `CSS`:

```
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: 'Roboto', 'Helvetica', sans-serif;
}

.container {
  display: grid;                       
  min-height: 100%;                    
  grid-template-rows: 48px [stage] auto 48px;  
  grid-template-columns: 100%;
}

#logo {
  color: #FFFFFF;
  font-size: 1.5em;
}

header {
  display: grid;
  grid-template-columns: auto [head-center] 832px auto;
  height: 48px;
  background-color: #000000;
}

header > nav {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: flex-start;
  align-items: center;
  grid-column-start: head-center;
  grid-column-end: span 1;
}

header > nav ul {
  margin: 0 0 0 auto;
}

header > nav ul li {
  display: inline;
  padding-left: 8px;
}

header > nav ul li a {
  color: #FFFFFF;
  text-decoration: none;
  text-transform: uppercase;
}

header > nav ul li a:hover {
  color: #AAAAAA;
}

main {
  display: grid;
  grid-template-columns: auto [main] 832px auto;
  grid-template-rows: auto;
  grid-row-start: stage;
  grid-row-end: span 1;
}

main > div.content {
  grid-column-start: main;
  grid-column-end: span 1;
}

main > div.content .hero {
  height: 300px;
  width: 100%;
  background-color: #000000;
  color: #FFFFFF;
}

main > div.content .hero h3 {
  padding: 16px;
}

footer {
  display: grid;
  grid-template-columns: auto [foot-center] 832px auto;
  grid-template-rows: 48px;
  background-color: #000000;
}

footer > nav {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: flex-end;
  align-items: center;
  grid-column-start: foot-center;
  grid-column-end: span 1;
}

footer > nav > .siteinfo {
  color: #FFFFFF;
}
```

**I have some other nifty things in here to make things look pleasant, but we should really focus on where `display: grid` and `display: flex` is used**.

The `.container` element is our top-level grid:

```
.container {
  display: grid;                       
  min-height: 100%;                    
  grid-template-rows: 48px [stage] auto 48px;  
  grid-template-columns: 100%;
}
```

Here, we use `grid-template-rows` to define our top-level rows (from top to bottom). These can be a fixed size, a percentage or `auto`. Each specification under the property is mapped to a child item in the order of definition. For example, the first `48px` entry is my first row, `auto` (which is aliased to `stage`) is my second row, and `48px` is my final and last row. I've also specified that I want the `grid-template-columns` to expand the full width of my container.

Now that I've done this, I have to think about the direct child elements that I create from that grid element because all the properties I applied are to the direct children of this parent element.

My child elements (my grid items) from this parent of `.container` are `header`, `main` and `footer`. I define properties on these items to tell them where they should go on the grid.

Let's take a look at `main`:

```
main {
  display: grid;
  grid-template-columns: auto [main] 832px auto;
  grid-template-rows: auto;
  grid-row-start: stage;
  grid-row-end: span 1;
}
```

I'm doing several things here. I'm defining another grid under the top-level `.container` grid and I'm telling this grid item to start where the `stage` row begins and then extend (or `span`) 1 cell space down from it. If I had not aliased the starting row to `stage`, then I would have to count the number of rows down I would want to start from and enter that number (in this case, it would have been `2`).

**This is basically all there is to it.** While this is not like the HTML `<table>` tag, it's mental model of placement is very similar. You can think of `colspan` and `rowspan` working very much like the `span` property above.

**To me, the two most important concepts to get are the parent element where the `grid` layout is defined and the child elements where each "item" is defined**. An item is a DOM element that is mapped as content to a certain location in the grid.

**You can nest `grid` to get more complex layouts.** I did this so I could extend the backgrounds of my header and footer across the width of my page, but also maintain an "internal" grid on the `main` element where content would be centered with margins that have an automatic width.

**While I used `grid` to manage the layout, I used** `flex` **to manage the positioning behavior of child elements within the layout.** This is not just vertical and horizontal positioning, but relative spacing between children and even ordering. Flex is great at this sort of thing and can (and has) been used for layouts, but in the end, it starts to really feel hacky as your DOM gets more complex. So use `grid` if you are trying to design big picture components.

**For** `grid` **, there are also more things to think about like lines, tracks, areas and cells. I've also made heavy use of aliases.** These are all things you should play with and understand.

**So it's best to get experimenting.** Go ahead and copy the HTML directly to a file and save it as `index.html` and then save the CSS as `styles.css` and plop them in a folder.

Assuming you have Python 3 installed and you have a unix shell available you can serve these up:

```
$ cd YOUR_FOLDER
$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
```

Then open up a browser to `http://localhost:8000` and start adjusting CSS values using the built-in developer console in your browser or edit the files directly on disk and hit refresh on the browser for every change you want to make.

**Also, try it with some of the mobile views. You'll quickly see the width is fixed. Can you make it work in a fluid or responsive way?** Here's a hint: Look at the HTML and CSS of [this blog site](https://angelolakra.com).

## In Summary

**There are lots of things you can do with grid.** You can throw in media queries and you can make your layouts completely fluid if you wish. Most modern browsers support grid and flex.  Take a look at [the grid guide](https://css-tricks.com/snippets/css/complete-guide-grid/) and [the flexbox guide](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) or at [the spec itself](https://www.w3.org/TR/css-grid-1/) to get more information and most importantly – throw away your hacks!

* * *

#### References

1. CSS Grid Spec: [Placing Items](https://www.w3.org/TR/css-grid-1/#overview-placement) 
2. CSS 2 Spec: [Minimum and maximum heights: 'min-height' and 'max-height'](https://www.w3.org/TR/CSS2/visudet.html#min-max-heights)