Creating a simple WordPress blogging layout with CSS Grid and Flexbox

CSS has come a long, long way and throughout the very recent years has steadily matured to become more than a simple styling specification which required hacks for many complex (or simple) things. With constant improvements like the introduction of e.g. flexbox, custom properties, and more, the design developer’s life has become dramatically easier. One of the most recent additions into the language’s specification is CSS Grid, which aims to remove any layout limitations the language had before (even by flexbox).

CSS Grid is designed to be the most powerful layout system CSS has to offer. Unlike flexbox, which is mostly a one-dimensional positioning system with limited two-dimensional support, CSS Grid handles both dimensions (i.e. rows and columns) with greater versatility.

As CSS Grid is extremely complex (it introduces more than a dozen new properties with near infinite combinations) this post will focus on a general overview of a basic blogging layout, much like the ones we usually see on WordPress, explore some of the required properties to create this layout, and make an attempt to distinguish layout responsibilities between CSS Grid and flexbox.

The desired blogging layout

We’ll be creating one of the all time’s classic layouts for our blog, the “Holy Grail layout“, which has the following requirements:

  1. A full-site width header on top and a full-site width footer at the bottom.
  2. A fluid-width content on the center with two fixed-width sidebars (either on the right or left, both on the right, or both on the left).
  3. The content area must come first in the HTML regardless of the visual positioning of the sidebars.
  4. All sidebars and the content area must always be of equal height, regardless of their content.
  5. The footer must stick at the bottom of the viewport even when there’s not enough content to span the viewport height
  6. The layout should be responsive,  all its areas spanning the whole viewport width one under the other (with their order as a matter of preference, in our scenario we’ll show the main content before the sidebars on mobile).

Achieving the Holy Grail layout used to be a major pain and required a lot of hacks, sometimes even flat out impossible without some JavaScript. Nowadays with flexbox it’s possible to implement it in a clean way, time to see how we’d go about doing it in CSS Grid and compare!

The markup

The layout’s structure is very simple, all we need is a few elements:

<div class="grid-container">
  <header class="header">Header</header>
  <main class="main">Main Content</main>
  <div class="sidebar sidebar-left">Left Sidebar</div>
  <div class="sidebar sidebar-right">Right Sidebar</div>
  <footer class="footer">Footer</footer>
</div>
Holy Grail layout HTML requirements for CSS Grid

We’ll see if we can maintain this simplicity in the HTML with flexbox.

The Grid

Generally there are a couple of different ways to go about this with CSS Grid but we’ll use the most interesting one which is grid template areas! Here’s all it takes:

.header { grid-area: header; }
.main { grid-area: main; }
.sidebar-left { grid-area: sidebar-left; }
.sidebar-right { grid-area: sidebar-right; }
.footer { grid-area: footer; }

.grid-container {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: auto auto 1fr auto auto;
  grid-template-areas: "header"
                       "sidebar-left"
                       "main"
                       "sidebar-right"
                       "footer";
}

@media (min-width: 540px) {
  .grid-container {
    grid-template-columns: 150px 1fr 150px;
    grid-template-rows: auto 1fr auto;
    grid-template-areas: "header header header"
                         "sidebar-left main sidebar-right"
                         "footer footer footer";
  }
}
The Holy Grail layout in CSS Grid

Keep in mind we’re writing this in a “mobile first” approach, so the actual styles making the layout are inside the media query. Let’s break down what we’ve done here.

In CSS Grid you work with the layout by applying CSS rules to both a parent element (the Grid Container) and to that element’s direct children (the Grid Items), much like with flexbox.

Setting the layout’s grid size

We can easily define the layout’s grid size with the grid-template-columns and grid-template-rows properties, providing a space separated list of values to each one of them. Each of those values is called a “track size” and is used to determine what amount of the Grid Container’s width a column or a row should span.

grid-template-columns: 150px 1fr 150px;
grid-template-rows: auto 1fr auto;
Columns and rows

In our case, we’ve defined a 3 by 3 grid where the first and last columns span 150px and the middle one spans 1fr of the remaining available width (so the entire remaining width). fr is a new type introduced in CSS Grid, and it means “fraction of the free space in the grid”. For the rows we’ve done something very similar, and simply replaced the fixed values with “auto”, because we don’t want the header and the footer to be height constrained.

Laying out the content

What’s cool is that CSS Grid allows us to give names to our Grid Items using the grid-area property and place them on the Grid Container using the grid-template-areas property. This interesting new behavior allows us to compose our layout “visually”, simply by declaring how many rows and columns each element should span.

/* For mobiles, we want every grid area to span an entire row */
.grid-container {
  grid-template-areas: "header"
                       "sidebar-left"
                       "main"
                       "sidebar-right"
                       "footer";
}

/* For desktops, we construct the layout as we wish, visually! */
@media (min-width: 540px) {
  .grid-container {
    grid-template-areas: "header header header"
                         "sidebar-left main sidebar-right"
                         "footer footer footer";
  }
}
Visually constructing the layout

And this pretty much all we have to do! Here’s how it looks (try opening the pen on a new window and resize your browser for the mobile version):

0

Now do it again

Let’s try with flexbox:

<div class="grid-container">
  <header class="header">Header</header>
  
  <div class="main-wrapper">
    <main class="main">Content</main>
    <div class="sidebar sidebar-left">Left Sidebar</div>
    <div class="sidebar sidebar-right">Right Sidebar</div>
  </div>
 
  <footer class="footer">Footer</footer>
</div>
Markup for flexbox solution

For the flexbox solution we need an additional HTML element, to act as a “row wrapper”.

.grid-container {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.main-wrapper {
  display: flex;
  flex-direction: column;
  flex: auto;
}

.main {
  flex: auto;
}

@media (min-width: 540px) {
  .main-wrapper {
    flex-direction: row;
    flex: 1;
  }
  
  .sidebar {
    flex: none;
    width: 150px;
  }
  
  .sidebar-left {
    order: -1;
  }
  
  .main {
    flex: auto;
  }
}
Holy Grail layout in flexbox

Exactly the same functionality and about the same amount of code, although with a bit added complexity. I have to admit that the CSS Grid solution is easier to read and it makes it possible to actually visualize what the end result will be. Take note that for flexbox we also needed an extra wrapper element without any real semantics, which is one of its drawbacks when it comes to layout.

Where does Flexbox fit in, then?

Flexbox and CSS Grid might appear to have some overlap in functionality, and as we start working with both their separating lines will surely become more distinct.

The thing to keep in mind is that CSS Grid was designed for the “bigger picture”. It excels in constructing and managing the major regions within a page in two dimensions without the need of extra wrappers, where flexbox is mostly one-dimensional and excels in “micro-management” and positioning smaller parts of a components in the interface.

The two tools work very well together. Let’s see now, under our WordPress blogging layout paradigm, how we’d use flexbox to style a list of blog posts in the main content area.

The article’s markup will be pretty standard:

    <article class="entry">
      <figure class="entry-thumb">
        <img src="https://placehold.it/540x400" alt="">
      </figure>

      <div class="entry-content">
        <header class="entry-header">
          <h3 class="entry-title"><a href="#">Hello, World</a></h3>

          <div class="entry-meta">
            2 Comments
          </div>
        </header>
        <p>Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!</p>
      </div>
    </article>
Article markup

And we’ll use flexbox to “micro-manage” the article’s different parts. For example, we’ve chosen to go with a “media item” layout, where the post thumbnail will be on the left, and the content (title, excerpt, and comments) on the right. On top of that we’d like to position the post’s comments number text directly opposite of the title.

@media (min-width: 767px) {
  .entry {
    display: flex;
  }

  .entry-thumb {
    width: 100px;
    flex: none;
    margin-right: 15px;
  }

  .entry-header {
    display: flex;
    align-items: center;
  }

  .entry-meta {
    margin-left: auto;
  }
}
Blog post styles with flexbox

The above, together, produce the following desired result:

0

As you see, we had to micro-manage a few of the article’s elements, its thumbnail, the comments number text, and in a real life scenario or a more complicated component we’d surely have a lot of fine-tuning work which wouldn’t make much sense to achieve with CSS Grid.

Here’s our complete blogging layout:

0

Browser support

CSS Grid looks definitely looks promising and has reached Candidate Recommendation status a few months back. This means that it will soon become a finalized standard plus all modern browsers support it right this moment. If you’re one of the lucky ones that don’t need to support IE you could probably start using it today!

If you want to learn more about how CSS Grid works here’s some reading material:

What are your thoughts on CSS Grid? How do you see it being different than flexbox, and are you using it in any of your WordPress websites or themes? Let us know in the comments!

Subscribe to our newsletter.

Get fresh WordPress content straight into your inbox. We hate spam more than you do.

Leave a Reply

Your email address will not be published. Required fields are marked *