Use Flexbox to create a sticky header and sidebar with flexible content

Andrea Pereira de Almeida by Andrea Pereira de Almeida

Use Flexbox to create a sticky header and sidebar with flexible content

Andrea Pereira de Almeida Create an html template that contains a sticky header, a sticky, flexible-width sidebar, and a flexible main content container

posted in Design on March 7, 2017 by Andrea Pereira de Almeida

While re-designing the CanJS website, I ran into a few issues coding the new layout.  I needed a way to create a fixed header and a fixed flexible sidebar that would adjust its width based on its content.  This meant that the main content container also needed to flex to accommodate more or less sidebar content. This post will show you how I created this layout hack using Flexbox and I will explain how to create your own html template that contains the following:

  1. A sticky header
  2. A sticky, flexible-width sidebar
  3. A flexible main content container (that changes width based on the content of the sidebar)

Notice how CanJS.com’s main content container changes its width based on the width of the sidebar:

canjs1.gif

 

Also, the sidebar and main content container scroll independently:

canjs2.gif

 

Page structure

I first set the height of the html and body containers to 100% and disabled page scroll. I created two columns inside the body that were flexible in width and spanned the height of the page.  The left column contained the side navigation and the left side of the header. The right column contained the page’s main content and the right side of the header. I enabled scrolling within the sidebar and main content containers.

wireframe6.svg

Note:  You could place the header outside the two columns.  I chose to place it within the columns because I wanted to align my navbar links in the right header with the left edge of the main content container.

 

HTML

Use this html structure as a starting point and add your own content:

<body>
    <div id="left" class="column">
        <div class="top-left"></div>
        <div class="bottom"></div>
    </div>
    <div id="right" class="column">
        <div class="top-right"></div>
        <div class="bottom"></div>
    </div>
</body>

 

CSS

html {
    height: 100%;
}

body {
    height: 100%;   
    overflow: hidden;  /*makes the body non-scrollable (we will add scrolling to the sidebar and main content containers)*/
    margin: 0px;  /*removes default style*/
    display: flex;  /*enables flex content for its children*/
    box-sizing: border-box;
}

.column {
    height: 100%;  /*allows both columns to span the full height of the browser window*/
    display: flex;
    flex-direction: column;  /*places the left and right headers above the bottom content*/
}

#left {
    flex-shrink: 0;  /*makes sure that content is not cut off in a smaller browser window*/
}

.top-left {
    flex-shink: 0;
}

.top-right {
    flex-shrink: 0;
    display: inline-flex;
}

ul {
    display: inline-flex;
    list-style: none;
}

.bottom {
    flex-grow: 1;  /*ensures that the container will take up the full height of the parent container*/
    overflow-y: auto;  /*adds scroll to this container*/
}

 

That’s it

You now have an html template based on Flexbox.

Want to learn more about Flexbox? This is a great place to start.

Want to see this layout in action? Check it out on the CanJS website.

Want to see the full demo?  Play around with it in JS Bin.

Create better web applications. We’ll help. Let’s work together.