Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

html

css

flexbox

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>
like image 976
Matthew David Jankowski Avatar asked Dec 03 '25 17:12

Matthew David Jankowski


2 Answers

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 the last two 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

like image 159
Michael Benjamin Avatar answered Dec 06 '25 11:12

Michael Benjamin


Here is an example with a nested flex to correctly position the upper row (no floats or inline, just flex!):

Demo: http://codepen.io/aaronvanston/pen/XjgNjP

The upper row can have as many columns with inside it and it will automatically adjust the widths.

It has a sticky footer as yours does.

The HTML is relatively simple:

html {
  height: 100%;
}
body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

.main {
  display: flex;
  flex: 1 0 auto;
}

.nav {
  flex: 0 0 12em;
}

.content {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

.row {
  display: flex;
  flex: 1 0 auto;
  flex-direction: row;
  
}
.col {
  flex: 1 0 auto;
}

/* TEMP CODE FOR THIS TEST, REMOVE FOR ACTUAL USE
*/
body {
  text-align: center;
}

*{
  box-shadow:inset 0px 0px 0px 1px #f00;
}
<header clas="header">Header</header>
<main class="main">
  <nav class="nav">
    Nav
  </nav>
  <section class="content">
    <div class="row">
      <div class="col">
        Upper Left
      </div>
      <div class="col">
        Upper Middle
      </div>
      <div class="col">
        Upper Right
      </div>
    </div>
    <div class="row">
      Middle
    </div>
    <div class="row">
      Lower
    </div>
  </section>
</main>
<footer class="footer">Footer</footer>
like image 36
Aaron Vanston Avatar answered Dec 06 '25 10:12

Aaron Vanston



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!