DEV Community

Yash Jain
Yash Jain

Posted on

Build collapsible sidebars using just CSS

While working on a NextJS project I stumbled across a situation where I wanted my sidebar component to be collapsible. At first glance it looked simple and easily doable using react hooks such as useState to maintain toggle state.
But using hooks would have forced me to make my component client side, which I didn't wanted.
So I wandered into the sea of internet looking for possible solutions to my problem, and found out a backdoor to achieve my desired result and that way was .... drum roll .... Checkboxes, Yes you read it right, checkboxes would act as a toggler.
We can use checkboxes checked state to toggle our precious, little, server rendered side bar.
Keeping all this aside, let's move on to code straight away.
Note that I will be using tailwind css for styling.
Okay, so first let's setup a boilerplate code for our app, we want a sidebar and a main dashboard section. We can achieve that using below code

<main class="grid grid-cols-[auto_1fr] min-h-screen">
  <nav class="min-h-screen w-64 bg-red-500">
    <ul class="p-8">
      <li>Element 1</li>
      <li>Element 2</li>
      <li>Element 3</li>
      <li>Element 4</li>
    </ul>
  </nav>
  {/* Main Content */}
  <section class="px-8 py-12">
    Hello, dev!
  </section>
</main>
Enter fullscreen mode Exit fullscreen mode

Now that we have our boilerplate ready, we now come to the main part i.e. to add a button to toggle that sidebar. For that we will have to add in checkbox with label as an icon of toggle say hamburger. We will hide that checkbox since it will look ugly and just keep label to check/uncheck it.

<main ...>
  <div>
    <input type="checkbox" id="toggler" class="hidden"/>
    <label for="toggler" class="fixed top-1 left-4 z-50 cursor-pointer">
      &#9776;
    </label>
  </div>
  <nav ...>
...
Enter fullscreen mode Exit fullscreen mode

Cool, we have our checkbox. We just have to connect some wires so that we can somehow hide our menu when checkbox is unchecked and when it is checked show that menu.
We can achieve that using checked pseudo class.
Okay I got your hint, no bull sh**t we know all this, just show me the code.., yeah hold my milkshake

<main ...>
  <div>
    <input type="checkbox" id="toggler" class="hidden peer"/>
    <label for="toggler" class="fixed top-1 left-4 z-50 cursor-pointer">
    <nav class="min-h-screen w-64 bg-red-500 fixed z-40 hidden peer-checked:block">
...
Enter fullscreen mode Exit fullscreen mode

Yeah that was all you needed to achieve collapsible behavior.
What you want better styles so that you can just use it directly?
I got your back, here you go

<main class="grid grid-cols-[auto_1fr] min-h-screen">
  <input type="checkbox" id="toggler" class="hidden peer"/>

  <label for="toggler" class="fixed top-1 left-4 z-50 cursor-pointer peer-checked:hidden">
    &#9776;
  </label>
  <label for="toggler" class="fixed top-1 left-4 z-50 cursor-pointer hidden peer-checked:inline">
    X
  </label>

  <!-- overlay -->
  <div class="fixed inset-0 bg-black opacity-50 peer-checked:block hidden" />

  <nav class="min-h-screen w-64 bg-red-500 fixed z-40 transition-transform -translate-x-full peer-checked:translate-x-0">
    <ul class="p-8">
      <li>Element 1</li>
      <li>Element 2</li>
      <li>Element 3</li>
      <li>Element 4</li>
    </ul>
  </nav>

  <section class="px-8 py-12">
    Hello, collapsible sidebar is made just using CSS
  </section>
</main>
Enter fullscreen mode Exit fullscreen mode

Try it out in here
Edit CollapsibleSidebar

Hope I was helpful, checkout my dev portfolio here.

Top comments (0)