DEV Community

Cover image for Hide or show sidebar
Michel
Michel

Posted on • Originally published at blog.pagesd.info

Hide or show sidebar

I'm still working on a simple 2-column template. Today my goal is to hide the "sidebar" used for navigation.

An easy solution would be to add a "d-none" class to the "sidebar" (since I use Bootstrap), but that won't be enough because the "content" doesn't automatically take all the width.

Let's go step by step and see what we need to do:

  • Hide the "sidebar" => add a "hidden" class to it,
  • Make the "content" fill the whole screen => add a "full-width" class.

On the HTML side, this would look like:

<nav id="sidebar" class="hidden">
    ...
</nav>
<div id="content" class="full-width">
    ...
</div>
Enter fullscreen mode Exit fullscreen mode

And on the CSS side:

#sidebar.hidden {
    display: none;
}
#content.full-width {
    width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

And vice versa, when I need to display the navigation bar again:

<nav id="sidebar" class="visible">
    ...
</nav>
<div id="content" class="less-width">
    ...
</div>
Enter fullscreen mode Exit fullscreen mode

Then the CSS part:

#sidebar.visible {
    display: block;
}
#content.less-width {
    width: calc(100% - 299px);
}
Enter fullscreen mode Exit fullscreen mode

It works! Now let's see how to get the same result but with less complications.

My first attempt needs 4 different classes, whereas there are basically only 2 cases:

  • We show the "sidebar" and the "content" => sidebar = true (default),
  • We only display the "content" => sidebar = false (on demand).

What can be done with a single "no-sidebar" class:

  • By default this class is not used => the "sidebar" is visible,
  • And to hide the "sidebar", we just have to add this class.

To be clever, we can do this at the "wrapper" level, which includes "sidebar" and "content":

<div id="wrapper" class="no-sidebar">
Enter fullscreen mode Exit fullscreen mode

And this time I only need two CSS rules:

.no-sidebar #sidebar {
    display: none;
}
.no-sidebar #content {
    width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Much better!

Now, all we need is a button and a bit of Javascript to show or hide the "sidebar".

<button id="sidebar-toggle">Masquer / Afficher</button>
Enter fullscreen mode Exit fullscreen mode

The Javascript code is really simple (because jQuery will be used later for the forms):

<script src="js/jquery-3.4.1.min.js"></script>
<script>
    $(document).ready(function () {

        $("#sidebar-toggle").on("click", function () {
            $("#wrapper").toggleClass("no-sidebar");
        });

    });
</script>
Enter fullscreen mode Exit fullscreen mode

To summarize, we need just 4 elements to build a 2-columns template, with a switchable sidebar:

  • A "#wrapper" div to enclose all the content,
  • A "#sidebar" nav to contain the navigation menu,
  • A "#content" div to present the main content,
  • A ".no-sidebar" class when you need to hide the sidebar.

And finally, very little CSS (without styles used to presentation):

#wrapper {
    display: flex;
    width: 100%;
}

#sidebar {
    min-height: 100vh;
    position: fixed;
    width: 299px;
}

#content {
    min-height: 100vh;
    position: absolute;
    right: 0;
    width: calc(100% - 299px);
}

.no-sidebar #sidebar {
    display: none;
}

.no-sidebar #content {
    width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

And if necessary hide the "sidebar" when printing (as it is intended to contain navigational elements only):

@media print {
    #sidebar { display: none;}
    #content { width: 100%; }
}
Enter fullscreen mode Exit fullscreen mode

We can also just add the bootstrap "d-print-none" class to "sidebar".

Yay! My first animated GIF for centuries, or at least since the last century (created with https://ezgif.com/).

It wasn't complicated... So I would probably write a third part to work on the "artistic" side:

  • Use an icon to show or hide the sidebar,
  • Add an animation to switch from one state to another.

This post was originally published on blog.pagesd.info.
Cover image: Le petit musée de l'interrupteur.

Discussion (3)

Collapse
danielatwood profile image
Daniel Atwood

You could even animate it using transition and transform. Animating width is fairly expensive.

Collapse
michelc profile image
Michel Author

Yes, that's what I plan to do. But I'll have to find a trick because "display" doesn't work with CSS animation.

Collapse
danielatwood profile image
Daniel Atwood

I usually do this
@keyframes {
0%{...display: block}
99%{...display: block}
100%{...display: none}

}