---
title: "TailwindCSS on Rails: Minimize Collapsible Sidebar"
author: "Yaroslav Shmarov"
date: "2024-06-30"
canonical_url: "https://blog.superails.com/tailwind-collapsible-sidebar"
markdown_url: "https://blog.superails.com/tailwind-collapsible-sidebar.md"
description: "A ruby friend named Daniel emailed me a request for this feature: Here's how I implemented this feature before: Here's my simplified solution, Daniel: ✅…"
tags: ["rails","tailwindcss"]
license: "GNU AGPL v3. Credit Yaroslav Shmarov and link the canonical URL."
video_url: "https://www.youtube.com/watch?v=y1eDh0iELao"
---

# TailwindCSS on Rails: Minimize Collapsible Sidebar

A ruby friend named Daniel emailed me a request for this feature:

![email request for this blogpost](https://blog.superails.com/assets/images/tailwind-sidebar-request.png)

Here's how I implemented this feature before:

![Trezy collapsible sidebar](https://blog.superails.com/assets/images/trezy-collapsible-sidebar.gif)

Here's my simplified solution, Daniel:

![Tailwind collapsible sidebar](https://blog.superails.com/assets/images/taiwlind-sidebar-toggle-save.gif)

- ✅ Collapsible sidebar
- ✅ Save state
- ✅ Elegant solution

First, create a stimulus controller to collapse sidebar. Write the current state to cookies

```js
// app/javascript/controllers/sidebar_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["sidebarContainer"];

  toggle(e) {
    e.preventDefault();
    this.switchCurrentState();
  }

  switchCurrentState() {
    const newState = this.element.dataset.expanded === "true" ? "false" : "true";
    this.element.dataset.expanded = newState;
    document.cookie = `sidebar_expanded=${newState}`;
    // document.cookie = `sidebar_expanded=${newState}; path=/`;
  }
}
```

The toggle can be triggered by a button like this:

```ruby
<%= button_to "Toggle", nil, data: { action: "click->sidebar#toggle" }
```

Toggling the button will update `cookies[:sidebar_expanded]`.

This is accessible in CSS via `[[data-expanded=false]_&]:`. You can use it as a **condition**!

Here's a sidebar that hides text like `"Home"` & `"Buttons"` when `data-expanded=false`:

```html
<!-- app/views/layouts/_sidebar.html.erb -->
<nav class="bg-slate-400 hidden md:flex flex-col text-center p-4 justify-between sticky top-20 h-[calc(100vh-80px)]" data-controller="sidebar" data-expanded="<%= (cookies[:sidebar_expanded] || true) %>">
  <div class="flex flex-col text-left">
    <%= link_to root_path do %>
      <span>🏠</span>
      <span class="[[data-expanded=false]_&]:hidden">Home</span>
    <% end %>
    <%= link_to buttons_path do %>
      <span>🔘</span>
      <span class="[[data-expanded=false]_&]:hidden">Buttons</span>
    <% end %>
  </div>
  <div class="text-left">
    <%= button_to nil, data: { action: "click->sidebar#toggle" } do %>
      <span class="[[data-expanded=true]_&]:hidden">➡️</span>
      <span class="[[data-expanded=false]_&]:hidden">⬅️</span>
      <span class="[[data-expanded=false]_&]:hidden">Toggle</span>
    <% end %>
  </div>
</nav>
```

🤠 Voila!
