Matthew David Jankowski Matthew David Jankowski - 2 months ago 12
CSS Question

How to nest content inside a flex box 'holy grail' layout?

My goal is to build a 'Holy-Grail' based layout with flex. The main content area needs to have additional content.HolyGrail with nested content in main section

I am having real trouble aligning the 'Upper Content Left, Upper Content Center, Upper Content Right, Middle Content, and Lower Content' alongside one another and filling the available space. Here is a codepen I modified in an attempt to nest the content.



body {
margin: 0;
}

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

.content {
display: flex;
flex: 1;
}

.contentMain {
flex: 1;
background: lightblue;
min-width: 10em;
}

.nav, .ads {
/* 12em is the width of the columns */
flex: 0 0 12em;
}

.nav {
/* put the nav on the left */
order: -1;
background: salmon;
}

.ads {
background: green;
}

header, footer {
background: #ccc;
padding: 4em 1em;
}


/*Nested Content*/
.ucleft{
background-color:gray;
width: 30%;
float:left;
}

.uccenter{
background-color:red;
width: 30%;
display:inline-block;
}

.ucright {
background-color:lightgray;
width:30%;
float:right;
}

.middlecontent{
background-color:blue;
width:100%;
}

.lowercontent {
background-color:orange;
width:100%;
}

<!-- currently not working in IE, don't know why -->
<body class="page">
<header>Header</header>
<div class="content">
<main class="contentMain">
<div class="upperContainer">
<div class="ucleft">UC Left</div>
<div class="uccenter">UC Center</div>
<div class="ucright">UC Right</div>
</div>
<div class="middlecontent">Middle Content</div>
<div class="lowercontent">Lower Content</div>
</main>
<nav class="nav">Nav</nav>

</div>
<footer>Footer</footer>
</body>




Answer

There are several ways to construct this layout. Here's just one:

  • You don't need floats, so I removed them.
  • You don't need display: inline-block. Also removed.
  • You have an unnecessary container. Removed.

For this particular method, the five content items are wrapped in a row wrap flex container.

The first three items are given a width of 33.33%. The remaining items have a width of 100%.

This means the first three items will consume all the space in the first row, forcing subsequent items to create additional rows.

Tested in Chrome, Firefox, Edge and IE11.

.page {
  display: flex;
  height: 100vh;
  flex-direction: column;
  margin: 0;
}
.content {
  display: flex;
  flex: 0 0 60vh;
}
.contentMain {
  flex: 1;
  background: lightblue;
  display: flex;
  flex-direction: row;
  /* default setting; can be omitted */
  flex-wrap: wrap;
}

.nav, .ads {
  /* 12em is the width of the columns */
  flex: 0 0 12em;
}
.nav {
  /* put the nav on the left */
  order: -1;
  background: salmon;
}
.ads {
  background: green;
}
header, footer {
  flex: 0 0 20vh;
  background: #ccc;
}

/*Nested Content*/
.ucleft {
  flex: 1 0 33.33%;
  background-color: gray;
}
.uccenter {
  flex: 1 0 33.33%;
  background-color: red;
}
.ucright {
  flex: 1 0 33.33%;
  background-color: lightgray;
}
.middlecontent {
  flex: 0 0 100%;
  background-color: blue;
}
.lowercontent {
  flex: 0 0 100%;
  background-color: orange;
}
<body class="page">
  <header>Header</header>
  <div class="content">
    <main class="contentMain">
      <div class="ucleft">UC Left</div>
      <div class="uccenter">UC Center</div>
      <div class="ucright">UC Right</div>
      <div class="middlecontent">Middle Content</div>
      <div class="lowercontent">Lower Content</div>
    </main>
    <nav class="nav">Nav</nav>
  </div>
  <footer>Footer</footer>
</body>

revised codepen

Comments