Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexbox Holy Grail Layout: Fixed Header, Fixed Left Nav, Fluid Content Area, Fixed Right Sidebar

Tags:

I'm attempting to build the "Holy Grail" layout using Flexbox.

  • Fixed Header
  • Fixed, Collapsible, Scrollable Left Nav
  • Flexible Content Area
  • Fixed, Collapsible, Scrollable Right Nav

See below:

enter image description here

I have everything working, except for the height of the "app" area underneath the header. Right now it's 100vh (100% of the viewport height), but this includes the 64px header.

I attempted calc(100vh - 64px), but that doesn't jive well with flex.

Here's my basic HTML structure:

<main>
    <header></header>
    <app>
        <nav>Left Nav</nav>
        <article>Content</article>
        <aside>Right Nav</aside>
    </app>
</main>

And the supporting CSS:

main {
    display: flex;
    flex-direction: column;
}

header { 
    z-index: 0;
    flex: 0 0 64px;
    display: flex;
}

app {
    flex: 1 1 100vh;
    display: flex;
}

nav {
    flex: 0 0 256px;
    order: 0;
}

article {
    flex: 1 1 100px;
    order: 1;
}

aside {
    flex: 0 0 256px;
    order: 2;
}

- - - Full jsFiddle Here - - -

- - - Simplified jsFiddle Here - - -

like image 239
Jon Avatar asked Nov 04 '15 05:11

Jon


People also ask

Why is it called Holy Grail layout?

- In web design, there's this layout that's referred to as the Holy Grail. It's called the Holy Grail because it's a great idea, but up until now, it's been pretty much impossible to actually attain. The Holy Grail layout looks something like this. You have a header that spans the full width of the screen.


1 Answers

There were some CSS conflicts with <main> and <body>, and all I had to do was remove the <main> wrapper, then add the flex definitions directly to the page body.

- - - Here's the full working jdFiddle - - -

- - - Here's the simplified jdFiddle - - -

html,
body {
  margin: 0;
  height: 100%;
  min-height: 100%;
}

body {
  margin: 0;
  display: flex;
  flex-direction: column;
}

header {
  z-index: 0;
  flex: 0 64px;
  display: flex;
}

app {
  flex: 1;
  display: flex;
}

nav {
  flex: 0 0 256px;
  order: 0;
}

article {
  flex: 1;
  order: 1;
  overflow: auto;
}

aside {
  flex: 0 0 256px;
  order: 2;
}
<header></header>
<app>
  <nav>Left Nav</nav>
  <article></article>
  <aside>Right Nav</aside>
</app>
like image 97
Jon Avatar answered Nov 01 '22 03:11

Jon