Chapter 3—Grid layout, powered by FlexBox

Flexbox.website

Implementation of the grid

We have learned the basic functionality of using Flexbox. We also learned the traditional float-based grid layout. Now we are ready to create our own Flexbox layout based on what we learned.

Time for Action—Migrating our grid into Flexbox

  1. Our basic CSS hasn’t changed much. We changed the .row into display:flex with flex-wrap. The other parts are same as the float-based grid.

    /* Border box */
    * {
      box-sizing: border-box;
    }
    
    img {
      max-width: 100%;
    }
    
    /* Grid */
    .row {
      /* if you need a largest width */
      width: 1920px;
      max-width: 100%;
      margin: 0 auto;
    
      display: flex;
      flex-wrap: wrap;
    }
    .row .row {
      margin-left: -10px;
      margin-right: -10px;
      width: auto;
      max-width: none;
    }
    
    .col {
      padding: 0 10px;
      min-width: 0;
    
      border: 1px dashed LIGHTGRAY; /* for debugging */
    }
  2. Our final outcome is to replace the width in column with something like flex: 0 1 50%; and flex: 0 1 100%;. The pertentage acts as the desired width value. But we don’t define the width. We define the flex-basis which is essentially the min-width of the element. Flexbox will calculate how much space each item takes based on this value.

  3. It’s very easy to define our mobile-first grid system by using the Scss’s list, loop and variable. In the code, we not only define the columns’ width, we also define classes for auto expand, shrink, vertical direction and horizontal direction. An extra hidden class allows us to hide element in smaller screen.

    $columns-count: 12;
    $screen-sizes: small medium large xlarge xxlarge;
    $breakpoints: 0 500px 1000px 1200px 1600px;
    @for $i from 1 through length($screen-sizes) {
      @media screen and (min-width: nth($breakpoints, $i)){
        .#{nth($screen-sizes, $i)}-vertical { flex-direction:column; }
        .#{nth($screen-sizes, $i)}-horizontal { flex-direction:row; }
        .#{nth($screen-sizes, $i)}-hidden { display: none; }
        .#{nth($screen-sizes, $i)}-auto   { display: block; flex: 1}
        .#{nth($screen-sizes, $i)}-shrink { display: block; flex: 0 1 auto}
        @for $j from 1 through $columns-count {
          .#{nth($screen-sizes, $i)}-#{$j} {
            display: block;
            flex: 0 1 calc( 100% / #{$columns-count} * #{$j} );
          }
        }
      }
    }

Implementation of block grid

Block grid is a grid system that we define how many items per roles inside the container. It trys to evenly distribute the items into the container within the items-limitation per role.

/* Block grid */
.block-grid {
  display: flex;
  flex-wrap: wrap;
}
.block-grid > * { flex: 1; }
@for $i from 1 through length($screen-sizes) {
  @media screen and (min-width: nth($breakpoints, $i)){
    @for $j from 2 through 10 {
      .block-grid.#{nth($screen-sizes, $i)}-up-to-#{$j} > * {
        flex: 0 1 calc( 100% / #{$j} );
      }
    }
  }
}

HTML that uses the grid

<header>
  <div class="row">
    <div class="small-12 col">
      <h1>Cake Shop</h1>
    </div>
  </div>
</header>
<div class="row">
  <nav class="small-12 medium-shrink xxlarge-2 col">
    <ul class="block-grid medium-vertical">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Clients</a></li>
      <li><a href="#">Contact Us</a></li>
    </ul>
  </nav>
  <aside class="small-hidden large-shrink xxlarge-2 col">
    <p>Sections</p>
    <ol>
      <li><strong>Section 1</strong>
        <ol>
          <li>Section 1.1</li>
        </ol>
      </li>
      <li>Section 2</li>
      <li>Section 3</li>
    </ol>
  </aside>
  <main class="small-12 medium-auto col">
    <article>
      <h1>Main Heading of the article</h1>
      <p>Introducing of the essay goes here.</p>
      <h2>Section 1—Photos</h2>
      <p>You’ll find a couple of images in the following that shows the flexbox-based block-grid system.</p>
      <div class="block-grid small-up-to-2 medium-up-to-3">
        <figure>
          <img src="http://placehold.it/300x300" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/350x300" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/700x400" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/500x300" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/500x600" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/300x300" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/300x300" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
        <figure>
          <img src="http://placehold.it/300x300" alt="placeholder image" />
          <figcaption>This is a placeholder.</figcaption>
        </figure>
      </div>
      <h3>1.1 Sub section</h3>
      <p>This is a paragraph of section 1.1. It’s the sub-section that conclude the section 1.</p>
      <h2>2. Section 2</h2>
      <p>We create more sections. An essay usually contains more than 1 section. This is the reason we put section 2 here.</p>
      <h2>3. Summary</h2>
      <p>This section summerize the entire article.</p>
    </article>
  </main>
  <div class="advertisement row">
    <div class="small-hidden xlarge-shrink col">
      <img src="http://placehold.it/160x600&text=ad." alt="Advertisement" />
    </div>
  </div>
</div>
<footer>
  <div class="row">
    <div class="small-12 col">
      CC0 Do anything license.
    </div>
  </div>
</footer>

Result and live demo

Here is the final result we get:

In small screen.

In small screen.

In medium screen.

In medium screen.

In large screen.

In large screen.

In extra large screen.

In extra large screen.

In xx-large screen.

In xx-large screen.

You can find the final code in the following CodePen demo.

http://codepen.io/makzan/pen/GJjMEL

You can find the PDF/ePub/Mobi edition at https://leanpub.com/flexbox-website. Buy now and read the book in your favorite reader.