Bootstrap 4 сніппет: адаптивне бічне меню

Bootstrap 4 сніппет: адаптивне бічне меню

Точніше, бічне меню, яке при зменшенні розміру браузера трансформується в стандартне для Bootstrap верхнє меню. Ну а щоб не було так вже нудно, додамо ще й акордеон для пунктів другого рівня. В кінці поста дам лінк на Codepen, де можна подивитися і вихідний код, і сніппет в дії.

HTML

Все просто до неподобства: копіюємо навігацію з сайту Bootstrap та трохи її змінюємо. Перш за все, в тег списку пунктів меню додамо клас sidenav та ідентифікатор navAccordion:

<nav class="navbar navbar-expand-lg navbar-dark fixed-top bg-dark">
  <a class="navbar-brand" href="#">Sidebar Nav</a>
  <button
    class="navbar-toggler"
    type="button"
    data-toggle="collapse"
    data-target="#navbarCollapse"
    aria-controls="navbarCollapse"
    aria-expanded="false"
    aria-label="Toggle navigation"
  >
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarCollapse">
    <ul class="navbar-nav mr-auto sidenav" id="navAccordion">
      ...
    </ul>
    ...

А в посилання, що вказують на пункти другого рівня додамо клас nav-link-collapse і, звісно, атрибути для акордеона, які знову ж таки можна подивитися на відповідній сторінці документації Bootstrap. Тобто пукнт меню з вкладеними підпунктами буде виглядати так:

<li class="nav-item">
  <a
    class="nav-link nav-link-collapse"
    href="#"
    id="hasSubItems"
    data-toggle="collapse"
    data-target="#collapseSubItems2"
    aria-controls="collapseSubItems2"
    aria-expanded="false"
  >Item 2</a>
  <ul class="nav-second-level collapse" id="collapseSubItems2" data-parent="#navAccordion">
    <li class="nav-item">
      <a class="nav-link" href="#">
        <span class="nav-link-text">Item 2.1</span>
      </a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">
        <span class="nav-link-text">Item 2.2</span>
      </a>
    </li>
  </ul>
</li>

 

CSS

Ключовий момент - медіа-запит для sidenav. Задамо абсолютне позиціонування з бажаної шириною і розтянемо бічну панель на всю висоту вікна. Також зазначимо відповідний для нашої мети flex-direction. При цьому не забудемо «відсунути» основний контент вліво на ширину, рівну ширині бічного меню:

@media (min-width: 992px) {
  .sidenav {
    position: absolute;
    top: 0;
    left: 0;
    width: 230px;
    height: calc(100vh - 3.5rem);
    margin-top: 3.5rem;
    background: #343a40;
    box-sizing: border-box;
    border-top: 1px solid rgba(0, 0, 0, 0.3);
  }

  .navbar-expand-lg .sidenav {
    flex-direction: column;
  }

  .content-wrapper {
    margin-left: 230px;
  }

  .footer {
    width: calc(100% - 230px);
    margin-left: 230px;
  }
}

 

Зрозуміло, щоб спрацювало абсолютне позиціонування для меню, потрібно задати відносне позиціонування для батька (тег html).

html {
    position: relative;
    ...
}

 

Крім вищеописаного, буде зовсім не зайвим показати користувачеві, що деякі пункти меню розкриваються. Для чого праворуч від таких пунктів додамо знак +, а в розкритому стані, відповідно, мінус (і хай допоможе нам з символами Font Awesome):

.nav-link-collapse:after {
  float: right;
  content: '\f067';
  font-family: 'FontAwesome';
}

.nav-link-show:after {
  float: right;
  content: '\f068';
  font-family: 'FontAwesome';
}

 

Класу nav-link-show в html коді в нас як би і немає, але при кліках на меню з підпунктами цим буде займатися JavaScript.

JavaScript

Завдання JS - при необхідності змінити мінус на плюс у розкритих пунктів меню, за винятком того пункту, на якому натиснули. У останнього ж будемо просто перемикати клас nav-link-show, тобто якщо його не було - додамо, якщо був - видалимо. jQuery дозволяє це зробити просто, без циклів і зайвого головного болю:

$(document).ready(function() {
  $('.nav-link-collapse').on('click', function() {
    $('.nav-link-collapse').not(this).removeClass('nav-link-show');
    $(this).toggleClass('nav-link-show');
  });
});

 

Наостанок обіцяне посилання на демо та вихідні коди: