DEV Community

Cisco Vlahakis
Cisco Vlahakis

Posted on

Creating a Sidebar with Active Links

Suppose we want to create a sidebar menu that tracks active links.

First, let's create the sidebar container div:

<div id="sidebar-container">

</div>
Enter fullscreen mode Exit fullscreen mode

Assume our data-sidebar-links are being passed from an ERB file:

<div id="sidebar-container" data-sidebar-links='<%= @sidebar_links %>'>

</div>
Enter fullscreen mode Exit fullscreen mode

Now, let's set a title at the top of the sidebar:

<div id="sidebar-container" data-sidebar-links='<%= @sidebar_links %>'>
  <div class="sidebar-heading">
    <%= @title %>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Now, we can loop through each link. We can place an href around a div containing an icon and title for the link:

<div id="sidebar-container" data-sidebar-links='<%= @sidebar_links %>'>
  <div class="sidebar-heading">
    <%= @title %>
  </div>
  <div id="menuContainer">
    <% @sidebar_links.each do |link| %>
      <a href="/<%= link.fetch(:path,'') %>" class="list-group-item sidebar-link">
        <i class="<%= link.fetch(:icon,'') %>"></i>
        <%= link.fetch(:title,'') %>
      </a>
    <% end %>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Now, let's tackle our JS. First, we are going to add a listener for when content has loaded in the DOM to make sure we add the listeners on the sidebar at the right time:

document.addEventListener('DOMContentLoaded', (event) => {

});
Enter fullscreen mode Exit fullscreen mode

Now, let's grab the url in the browser to see which link should be active. We are also going to set up a reference to the links:

document.addEventListener('DOMContentLoaded', (event) => {
  const currentPath = window.location.pathname;
  const sidebarLinks = document.querySelectorAll('.sidebar-link');
});
Enter fullscreen mode Exit fullscreen mode

Now, let's loop through each link and reset their active status. To do this, we will remove the active class style from all links then reset the active class style only to the link who's href is the browser's url:

document.addEventListener('DOMContentLoaded', (event) => {
  const currentPath = window.location.pathname;
  const sidebarLinks = document.querySelectorAll('.sidebar-link');
  sidebarLinks.forEach((link) => {
    link.classList.remove('active');
    if (link.getAttribute('href') === currentPath) {
      link.classList.add('active');
    }
  });
});
Enter fullscreen mode Exit fullscreen mode

Finally, we can add styling:

#sidebar-container {
  width: 20vw;
  height: 100vh;
  min-height: 100vh;
  background-color: black;
  color: #fff;
}
Enter fullscreen mode Exit fullscreen mode

#sidebar-container: This is a CSS ID selector. It selects the HTML element with id="sidebar-container". It sets the width to 20% of the viewport’s width (vw), the height to 100% of the viewport’s height (vh), and the minimum height to 100vh, ensuring that it always takes up at least the full height of the viewport. It also sets the background color to black and the text color to white.

#sidebar-container .sidebar-heading {
  font-size: calc(1.275rem + .3vw)!important;
  border-bottom: 1px solid #EEEEEE;
}
Enter fullscreen mode Exit fullscreen mode

#sidebar-container .sidebar-heading: This is a CSS descendant selector. It selects any element with the class .sidebar-heading that is a descendant of #sidebar-container. It sets the font size using a calc() function, which lets you perform calculations to determine CSS property values. The !important declaration increases the priority of this CSS rule.

#sidebar-container .list-group-item {
  display: flex;
  text-decoration: none;
  color: white;
  transition: background-color 0.3s;
  border: none;
  font-size: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

#sidebar-container .list-group-item: This selects any element with the class .list-group-item that is a descendant of #sidebar-container. It sets the display property to flex, allowing for flexible layouts. It also removes text decoration (like underlines), sets the color to white, adds a transition effect to the background color, removes the border, and sets the font size.

#sidebar-container .sidebar-heading,
#sidebar-container .list-group-item {
  padding: 1.25rem;
}
Enter fullscreen mode Exit fullscreen mode

#sidebar-container .sidebar-heading, #sidebar-container .list-group-item: This selects both .sidebar-heading and .list-group-item elements inside #sidebar-container and sets their padding.

#sidebar-container .list-group-item:hover,
#sidebar-container .list-group-item.active {
  background-color: #343a40;
}
Enter fullscreen mode Exit fullscreen mode

#sidebar-container .list-group-item:hover, #sidebar-container .list-group-item.active: This applies styles to .list-group-item elements when they are being hovered over (mouse pointer is on it) or they have the active class.

#sidebar-container .list-group-item i {
  font-size: 1.2em;
}
Enter fullscreen mode Exit fullscreen mode

#sidebar-container .list-group-item i: This selects i elements inside .list-group-item elements and sets their font size.

Hope you enjoyed creating a sidebar!

Top comments (0)