Three-Column Layout with Long Sidebars Using CSS Grid

Variation on the standard three-column layout, done with Grid.

The Finished Example Layout

header

main

footer

The Code

HTML
<div class="container">
  <header class="header">
    <p>header</p>
  </header>

  <!-- Replace <div> with <aside> if your content has one aside. For more than one, nest <aside> elements in the <div>. -->
  <div class="sidebar">
    <p>sidebar 1</p>
  </div>

  <main class="content">
    <p>main</p>
  </main>

  <!-- Ditto the previous note about <aside>. -->
  <div class="sidebar">
    <p>sidebar 2</p>
  </div>

  <footer class="footer">
    <p>footer</p>
  </footer>
</div>
  
CSS
/* Sections of Layout
-------------------------------------- */
/* Layout is stacked vertically by default (for narrower viewports), so give some breathing room between the sections. */
.container > * {
  margin-bottom: 10px;
}

/* Now let's apply grid for wider viewports. */
@media screen and (min-width: 40em) {
  .container > * {
    margin-bottom: 0;
  }
  /* Define the grid */
  .container {
    display: grid;
    grid-template-columns: 1fr 3fr 1fr;
    grid-gap: 10px 20px;
  }
  /* Place items on the grid */
  .header {
    grid-column: 1 / -1;
  }
  .sidebar {
    grid-row-end: span 2;
  }
  .content {
    grid-column: 2;
  }
}

/* Alternative Approach
-------------------------------------- */
/* There is more than one way to achieve the same result with Grid. The commented-out code below, which would replace all of the code above, shows how to use Grid's template areas feature. It's pretty ingenious: in the grid-template-areas property, you show where the various grid areas should appear on the grid.

For example, I've said below that:
  * the head grid-area should span all three columns of row one;
  * the side1 grid-area should occupy column one of row two;
  * the main grid-area should occupy column two of row two;
  * the side2 grid-area should occupy column three of row two;
  * and the foot grid-area should span all three columns of row three.

Below that part I've assigned a grid-area to the classes used on the layout's sections. The grid-areas assigned here are the ones used in grid-template-areas. For example, I set .header { grid-area: head; }. If I did .header { grid-area: page-header; } instead, I would need to change "head head head" in grid-template-areas to "page-header page-header page-header". (Please note that only one space between grid areas is required to indicate columns. You do not have to line up the columns in grid-template-areas as I have below.)

All told, when combining grid-template-areas with matching grid-area assignments, you can see what the layout will be just by glancing at the grid-template-areas value!
*/
/*
.container {
  display: grid;
  grid-template-columns: 1fr 3fr 1fr;
  grid-gap: 10px 20px;
  grid-template-areas:
    "head  head head"
    "side1 main side2"
    "foot  foot foot";
}

.header {
  grid-area: head;
}

.sidebar-1 {
  grid-area: side1;
}

.content {
  grid-area: main;
}

.sidebar-2 {
  grid-area: side2;
}

.footer {
  grid-area: foot;
}
*/
/* Generic styles for demo purposes
-------------------------------------- */
.container {
  font-family: Helvetica, Arial, sans-serif;
  margin-left: auto;
  margin-right: auto;
  max-width: 75rem;
}

.container > * {
  background-color: #ccc;
  padding: 1em;
}

/* Typically, you wouldn't specify a height or min-height on this, instead allowing your actual content (i.e., text, images, etc.) to dictate the height of your content area. But since this example has very minimal content, I've set a min-height to mimic a taller content area. */
.content {
  min-height: 350px;
}