Fluid fly-out sidebar with CSS3 Flexbox

Fly-out menus is a popular thing nowadays and if you’re like me and prefer to use Google before you try to build your own solution you probably found that there really isn’t any good solution out there that allows you to create a completely fluid fly-out sidebar where you can render any dynamic content and it will change its size accordingly. Until now!

Traditional off-canvas, fly-out, slide- and push sidebars forces the main content off the screen where as this solution just re-flows and shrinks the main content. A perfect solution for secondary dynamic information such as notifications or other types of metadata.

To the fun stuff!

The recipe is actually really easy. By using a combination of the CSS3 flexbox properties flex-auto and flex-grow we can render any type of content in the sidebar container and flexbox will take care of the rest.

First of we need some basic HTML5 structure.

<body>
<aside class=”sidebar is-visible”>
<p class=”sidebar-content”>sidebar content…</p>
</aside>
<main class=”content”>
<button class=”toggle-sidebar”>Toggle sidebar</button>
<p>main content..</p>
</main>
</body>

This should not surprise anyone. Basically we have an <aside> which will be the sidebar and the main content is placed in the <main> element. In this case we are using the <body> as a wrapper for our sidebar and main content but this pattern can be applied to any wrapper div with the relevant CSS properties.

It’s in the CSS where the real magic happens.

html, body  {
width: 100%;
height: 100%;
margin: 0;
}
body {
display: flex;
justify-content: flex-end;
}
.content {
display: flex;
min-height: 0;
flex-direction: column;
  flex-grow: 1;
flex-shrink: 0;
flex-basis: 100%;
}
.sidebar {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
  height: 100%;
}
.sidebar.is-visible  ~ .content {
flex-basis: 0;
}

First of we need to set the width and height properties on the html and body elements so that our wrapper, the <body>, can fill up the entire viewport. Because we want our sidebar to be on the left hand side we also set 
justify-content: flex-end; so that every flex item will align to the right which in combination with the flex-basis: 100%; and flex-shrink: 0; on the <main> content element will make the sidebar overflow to the right.

To show the sidebar all we need to do is toggle the .is-visible class that only resets the flex-basis property on the main content element which means that the flex-shrink and flex-grow property will decide how much space the content and sidebar should occupy.

Since we set flex-grow: 1; on the content and flex-grow: 0; on the sidebar, the sidebar will only take up as much space as it needs for it’s content while the main content will take up the rest.

A working sample can be found here: https://github.com/marcuslindfeldt/fluid-flexbox-flyout-sidebar/