Search code examples
htmlcssflexboxresponsive

How can I slide the sidebar out of view and make the content flexbox resize to fill the void?


My flexbox layout is based on Philip Walton's Holy Grail Layout.

I'm trying to create a slide in/slide out navigation sidebar much like these but using flexbox layout, not absolute positioned divs.

I've seen many flexbox sliding menus such as this Off Canvas Flexbox Menu, but they all seem to slide the article over the sidebar. I want the sidebar to push/pull the article when sliding in and out of view.

To achieve this I have been toggling the CSS display property between display:block and display:none. This works perfectly as the sidebar is hidden and the content is resized automatically to fill the new larger space. JSFiddle demonstrating display toggle.

However, when I try to use the translate properties such as transform:translateX(-12em) to slide the sidebar out of view the content remains in the same place and does not resize. This leaves a hole where the parent container can be seen. JSFiddle demonstrating the sliding toggle.

Question: How can I slide the nav out of view and make the article resize to fill the void?

Note: I would like to achieve this without using javascript.


Solution

  • Transforms are purely visual--they don't actually move the element from its layout location.

    Use margin-left instead.

    JSfiddle Demo

    html,
    body,
    main,
    article,
    nav,
    aside {
      height: 97%;
      box-sizing: border-box
    }
    body {
      background-color: #ccc;
      margin: 1.5%;
    }
    main {
      display: flex;
      flex-direction: row;
      flex: 1;
      overflow: hidden;
    }
    article {
      flex: 1;
    }
    nav,
    aside {
      /* 12em is the width of the sidebars */
      flex: 0 0 12em;
      transition: margin 0.3s ease
    }
    /* Checkbox hack to toggle nav visibility */
    
    input ~ nav {
      margin-left: -12em;
    }
    input:checked ~ nav {
      margin-left: 0;
    }
    <header style="background-color: #a4c400;color:#fff;padding:0.25em">
      <label for="toggle">Click to Toggle Nav</label>
    </header>
    <main style="background-color: #ccc;">
      <input id="toggle" type="checkbox" checked style="display:none" />
      <nav style="background-color: #8dd0f2;">Nav</nav>
      <article style="background-color:#fff">Article</article>
      <aside style="background-color: #8dd0f2;">Aside</aside>
    </main>