Подробное руководство: создание адаптивного сайдбара для COTONTI CMF

как превратить обычную боковую панель в современный адаптивный сайдбар, который на широких экранах всегда видим, а на мобильных устройствах плавно выезжает по нажатию кнопки-гамбургера.

Рейтинг на основе отзывов:
Звезд получено: 0
Oтзывов всего: 0
Средняя оценка: 0
Опубликовано в: Блог пользователей

Подробное руководство: создание адаптивного сайдбара для COTONTI CMF

 

Версия для публичной статьи – без полных листингов, но с подробным разбором ключевых моментов.


Введение

В этой статье мы шаг за шагом разберём, как превратить обычную боковую панель в современный адаптивный сайдбар, который на широких экранах всегда видим, а на мобильных устройствах плавно выезжает по нажатию кнопки-гамбургера. Все решения основаны на реальном проекте «COTONTI CMF» – сервисе мониторинга обменников. Мы не просто скопируем код, а поймём логику каждого решения, чтобы вы могли применить её в своих проектах.

К концу чтения вы будете точно знать:

  • Как правильно спроектировать HTML-структуру для гибкого сайдбара.
  • Как с помощью CSS-переменных и медиазапросов реализовать адаптивность и переключение тем.
  • Как разделить JavaScript на независимые модули, чтобы не запутаться.
  • Как обрабатывать открытие/закрытие сайдбара, блокировать прокрутку и работать с оверлеем.

Всё внимание мы уделим именно сайдбару – его разметке, стилизации и логике поведения. Второстепенной, но важной частью станет переключение светлой и тёмной темы, потому что оно напрямую влияет на внешний вид сайдбара. Остальные модули (вкладки, кнопки обмена, демо-поиск) упомянем кратко – они не являются фокусом статьи.


1. Архитектура и общая концепция

Прежде чем писать код, давайте представим, как должна работать страница.

На десктопе (ширина экрана больше 1024 пикселей) мы видим:

  • Шапку с логотипом, навигацией и кнопками.
  • Под шапкой – основную область, разделённую на две части: слева сайдбар шириной 300px, справа – основной контент.
  • Сайдбар приклеен к верху и не скроллится вместе со страницей – он остаётся на месте благодаря position: sticky.
  • Гамбургер (три полоски) скрыт.

На мобильном устройстве (ширина ≤1024px) поведение меняется:

  • Шапка становится компактнее, навигация исчезает, появляется гамбургер.
  • Сайдбар больше не часть потока – он фиксируется поверх контента, но изначально сдвинут за левый край экрана.
  • При нажатии на гамбургер сайдбар плавно выезжает слева, а основной контент затемняется полупрозрачным оверлеем.
  • Закрыть сайдбар можно тремя способами: кнопкой «Свернуть», кликом по оверлею или клавишей Escape.
  • После закрытия сайдбар уезжает обратно, оверлей исчезает, прокрутка страницы восстанавливается.

Дополнительно вся страница поддерживает две цветовые схемы – тёмную (по умолчанию) и светлую. Выбор сохраняется в localStorage.

Именно такой UX мы и будем воплощать. Ключевая идея – один HTML-код, а всё поведение определяют CSS-медиазапросы и небольшой JavaScript-модуль. Никакого дублирования сайдбара для мобильной и десктопной версий.


2. Подготовка файловой структуры

Для удобства поддержки мы разнесём код по отдельным файлам:

project/
  index.html
  css/
    styles.css
  js/
    theme.js
    sidebar.js
    tabs.js
    swap.js
    search-demo.js

Основные герои нашей статьи – index.html, css/styles.css и js/sidebar.js. Файлы theme.js и tabs.js мы затронем в контексте сайдбара. Остальные (swap.js, search-demo.js) оставим без подробного разбора – они решают локальные задачи и не влияют на адаптивность.


3. HTML-разметка: каркас и ключевые элементы

Начнём с index.html. Он содержит всю семантическую структуру, но ни строчки стилей или скриптов (кроме внешних библиотек Bootstrap и Font Awesome).

3.1. Шапка и гамбургер

Шапка (<header class="header">) разделена на три логические части:

  • Левая: кнопка-гамбургер + логотип.
  • Центральная: навигационное меню (скрыто на мобильных с помощью классов d-none d-lg-flex).
  • Правая: кнопка темы и кнопка «Войти».

Код гамбургера:

<button class="hamburger" id="hamburgerBtn">
  <i class="fas fa-bars"></i>
</button>

Изначально гамбургер скрыт через CSS (display: none), и только медиазапрос для ширины ≤1024px делает его видимым. Именно на этот элемент мы повесим обработчик клика для открытия/закрытия сайдбара.

3.2. Overlay – затемнение фона

Сразу после шапки, но до основного макета, идёт пустой <div>:

<div class="sidebar-overlay" id="sidebarOverlay"></div>

Он будет показан только в мобильной версии, когда сайдбар открыт. В десктопном режиме он постоянно скрыт (display: none). Его клик также будет закрывать сайдбар.

3.3. Основной контейнер layout и сайдбар

Главный контейнер <div class="layout"> объединяет сайдбар и основной контент. Это флекс-контейнер, который в десктопе выстраивает детей в строку, а на мобильных – в колонку.

Сам сайдбар (<aside class="sidebar" id="sidebar">) содержит несколько внутренних блоков:

  • Чипсы (кнопки-вкладки) «Все валюты» и «Избранное».
  • Поисковый блок с двумя полями и кнопкой обмена местами.
  • Контейнер со списком валют.
  • Заглушка для пустого избранного.
  • Кнопка «Свернуть» (показывается только на мобильных).

Важнейший идентификатор id="sidebar" позволяет JavaScript легко найти элемент.

Обратите внимание на начальный класс visible у заглушки избранного – мы используем его для управления видимостью через JS.

3.4. Основной контент и подвал

В <main class="main-content"> находится всё, что справа от сайдбара: заголовки, калькулятор, блог. Вёрстка калькулятора здесь не принципиальна для темы сайдбара.

Подвал стандартный, прижимается к низу страницы благодаря флексам.


4. CSS: стилизация и адаптивность сайдбара

Все стили собраны в css/styles.css. Мы сгруппировали их по смысловым блокам и снабдили комментариями. Разберём ключевые моменты, отвечающие за поведение сайдбара.

4.1. CSS-переменные и темы

В самом начале файла мы определяем переменные для тёмной и светлой тем. Переключение основано на атрибуте data-bs-theme у элемента <html>:

:root,
[data-bs-theme="dark"] {
  --sidebar-bg: #1b1e22;
  /* ... */
}
[data-bs-theme="light"] {
  --sidebar-bg: #f8f9fa;
  /* ... */
}

Сам сайдбар использует переменную:

.sidebar {
  background: var(--sidebar-bg);
  /* ... */
}

Таким образом, смена атрибута автоматически обновляет фон и другие цвета без перезагрузки страницы.

4.2. Базовые стили сайдбара для десктопа

По умолчанию сайдбар ведёт себя как sticky:

.sidebar {
  width: 300px;
  position: sticky;
  top: 56px;          /* высота шапки */
  height: calc(100vh - 56px);
  overflow-y: auto;
  transition: transform 0.3s ease;
  /* ... */
}

Почему sticky, а не fixed? Потому что нам нужно, чтобы сайдбар участвовал в потоке flex-контейнера и не перекрывал контент. Sticky работает именно так: элемент ведёт себя как обычный блок, пока не достигнет указанного top, а затем «прилипает». В результате контент справа никогда не заезжает под сайдбар.

4.3. Медиазапрос: мобильная версия

При ширине экрана 1024px и меньше срабатывает медиазапрос, который полностью переопределяет поведение сайдбара:

@media (max-width: 1024px) {
  .sidebar {
    position: fixed;
    top: 56px;
    left: 0;
    height: calc(100vh - 56px);
    transform: translateX(-100%);
    width: 280px;
    z-index: 1060;
  }
  .sidebar.open {
    transform: translateX(0);
  }
  .sidebar-close-mobile { display: block; }
  .layout { flex-direction: column; }
  /* ... */
}

Что здесь происходит:

  • Сайдбар становится fixed, чтобы находиться поверх контента.
  • Изначально он сдвинут за левый край на 100% своей ширины с помощью transform: translateX(-100%). Это скрывает его визуально.
  • Когда JavaScript добавляет класс open, применяется transform: translateX(0), и сайдбар плавно выезжает. Плавность обеспечивается transition: transform 0.3s ease, заданным в базовых стилях.
  • Увеличиваем z-index до 1060 (оверлей имеет 1050), чтобы сайдбар был поверх затемнения.
  • Кнопка закрытия, ранее скрытая (display: none), теперь показывается.
  • Основной контейнер layout переключается на вертикальное направление – контент уходит вниз.

Таким образом, один и тот же HTML-элемент адаптируется под разные устройства исключительно за счёт CSS.

4.4. Overlay

Оверлей изначально скрыт и активируется добавлением класса active через JavaScript:

.sidebar-overlay {
  display: none;
  position: fixed;
  top: 56px; left: 0;
  width: 100%; height: calc(100% - 56px);
  background: rgba(0,0,0,0.4);
  z-index: 1050;
}
.sidebar-overlay.active {
  display: block;
}

При клике на него мы убираем класс active, что скрывает затемнение.

4.5. Дополнительный адаптив для очень узких экранов

Второй медиазапрос (max-width: 600px) перестраивает поля калькулятора в столбик. К сайдбару это прямого отношения не имеет, но показывает гибкость подхода.


5. JavaScript: логика управления сайдбаром

Теперь перейдём к тому, что заставляет сайдбар открываться и закрываться. Код находится в js/sidebar.js и представляет собой чистый модуль без зависимостей от других скриптов.

5.1. Инициализация и поиск элементов

Всё начинается после полной загрузки DOM:

document.addEventListener('DOMContentLoaded', () => {
  const sidebar = document.getElementById('sidebar');
  const overlay = document.getElementById('sidebarOverlay');
  const hamburgerBtn = document.getElementById('hamburgerBtn');
  const closeBtn = document.getElementById('sidebarCloseBtn');
  if (!sidebar || !hamburgerBtn) return;
  // ... функции и обработчики
});

Мы проверяем наличие ключевых элементов и, если их нет, просто выходим – это позволяет использовать скрипт на страницах без сайдбара.

5.2. Функции открытия и закрытия

function openSidebar() {
  sidebar.classList.add('open');
  if (overlay) overlay.classList.add('active');
  document.body.style.overflow = 'hidden';
}
function closeSidebar() {
  sidebar.classList.remove('open');
  if (overlay) overlay.classList.remove('active');
  document.body.style.overflow = '';
}

Логика проста:

  • Добавляем/убираем класс open – именно он запускает CSS-анимацию выезда.
  • Добавляем/убираем класс active у оверлея.
  • Блокируем/разблокируем прокрутку страницы через overflow у body. Это важно, чтобы под оверлеем контент не скроллился.

5.3. Обработчики событий

На гамбургер вешается функция toggleSidebar, которая переключает состояние:

hamburgerBtn.addEventListener('click', () => {
  sidebar.classList.contains('open') ? closeSidebar() : openSidebar();
});

Кнопка закрытия и клик по оверлею вызывают closeSidebar().

Дополнительно мы слушаем нажатие клавиши Escape на всей странице:

document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape' && sidebar.classList.contains('open')) {
    closeSidebar();
  }
});

Так сайдбар можно закрыть без использования мыши – это улучшает доступность.

5.4. Обработчик ресайза – важная деталь

Представьте: пользователь открыл сайдбар на мобильном (ширина 600px), а затем повернул устройство или изменил размер окна до 1200px. Если ничего не предпринять, сайдбар останется в состоянии open, но так как медиазапрос уже не применяет transform, сайдбар встанет на своё обычное место и будет видим. Однако body останется с overflow: hidden, и страница перестанет скроллиться. Чтобы избежать этого, мы добавили:

window.addEventListener('resize', () => {
  if (window.innerWidth > 1024) {
    closeSidebar();
  }
});

При переходе в десктопный режим мы принудительно закрываем сайдбар, убираем оверлей и восстанавливаем прокрутку. Это делает интерфейс надёжным.

5.5. Почему мы не используем Bootstrap для сайдбара?

Многие проекты применяют offcanvas-компонент Bootstrap, но в нашем случае требовалось более гибкое решение: сайдбар на десктопах должен быть именно sticky, а не просто скрытым. Стандартный offcanvas всегда является fixed и требует дополнительной обёртки. Наш подход легче и даёт полный контроль над анимацией и поведением.


6. Переключение темы и его связь с сайдбаром

Хотя переключение темы не основная тема статьи, оно напрямую влияет на сайдбар, поэтому разберём ключевые моменты.

Задача модуля theme.js – управлять атрибутом data-bs-theme на элементе <html> и сохранять выбор в localStorage. Почему именно <html>, а не body? Потому что CSS-переменные, отвечающие за цвета, привязаны к этому атрибуту:

[data-bs-theme="light"] {
  --sidebar-bg: #f8f9fa;
}

Когда пользователь нажимает кнопку темы, мы считываем текущий атрибут, инвертируем его и обновляем:

html.setAttribute('data-bs-theme', newTheme);
localStorage.setItem('index-mono-theme', newTheme);

Всё! Все элементы, включая сайдбар, мгновенно перекрашиваются благодаря переменным.

В начальный момент мы проверяем сохранённое значение или системные предпочтения, чтобы сразу установить нужную тему без мигания. Для этого в <html> заранее прописан data-bs-theme="dark", а JS, если надо, меняет его на light. Это гарантирует, что до выполнения скрипта страница будет тёмной.

Иконка кнопки (луна/солнце) также обновляется в функции setTheme.

Такой подход изолирует логику темы от других модулей и позволяет легко её повторно использовать.


7. Вкладки в сайдбаре (tabs.js) – кратко

Файл tabs.js отвечает за переключение между «Все валюты» и «Избранное». Это часть сайдбара, но её реализация проста и не влияет на адаптивность. При клике на кнопку-чипс мы:

  • Переносим класс active на нужную кнопку.
  • Показываем/скрываем контейнер с валютами (allCurrenciesContainer).
  • Показываем/скрываем заглушку «Избранные направления отсутствуют» через класс visible.

Никакой сложной логики, только переключение видимости. Важно лишь проверить, что все элементы существуют.


8. Остальные модули: swap.js и search-demo.js

Эти файлы решают локальные задачи и не требуют детального разбора в рамках статьи про сайдбар.

swap.js содержит функцию, которая меняет местами значения двух полей (по их id) – это нужно для удобства пользователей. Кнопки обмена есть и в сайдбаре, и в основном калькуляторе.

search-demo.js – временная заглушка, выводящая alert при нажатии на кнопку «Найти». В будущем сюда можно добавить AJAX-запрос.

Их наличие демонстрирует, как можно добавлять новые функции, не затрагивая основную логику сайдбара.


9. Почему такое разделение важно

Вынос стилей в отдельный файл и разбиение JavaScript на модули даёт несколько преимуществ:

  1. Чистота HTML – разметка остаётся семантичной и легко читаемой.
  2. Переиспользование – модуль theme.js можно подключить на любой странице, где нужна тема.
  3. Простота поддержки – чтобы исправить баг с сайдбаром, вы идёте в один файл sidebar.js.
  4. Параллельная работа – несколько разработчиков могут одновременно править разные модули без конфликтов.

Наш проект не использует сборщики (Webpack, Vite) и ES6-импорты, но это осознанное решение – для небольшого сервиса достаточно простого разделения с помощью defer.


10. Заключение

Мы прошли весь путь от идеи до полностью рабочего адаптивного сайдбара. На широких экранах он всегда на виду, на мобильных – выезжает по требованию. Цветовая тема переключается без перезагрузки. Код разделён на логические части, и каждая строка имеет понятное объяснение.

Этот подход вы можете применить в любом проекте: интернет-магазине, админке, лендинге. Главное – понимать, что адаптивность закладывается в CSS, а JavaScript лишь управляет состояниями.

Теперь у вас есть не просто набор файлов, а глубокое понимание того, как сделать современный, удобный и поддерживаемый интерфейс. Успешной разработки!



Отзывы

Отзывов пока нет


Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Обсуждение страницы в Telegram

Похожие страницы

Создание оптимально структурированной страницы товара для SEO в 2025 году
1 Как создать страницу товара для высоких позиций в поиске? Полное руководство по SEO, семантике и UX в 2025
Создание и управление темами на различных CMS (системах управления контентом)
2 Создание и управление темами на различных CMS (системах управления контентом) — это важная часть работы над сайтом,
XTemplate и Controllers в Cotonti: Руководство для разработчиков
3 XTemplate и хуки в Cotonti: руководство разработчикаШаблонизатор XTemplate и система хуков образуют фундамент
Google обновляет руководство по SEO для начинающих
4 Google обновляет руководство по SEO для начинающих, чтобы сосредоточиться на целевой аудитории Руководство Google по
Установка Open Server Panel 6.5.1: Руководство для новичков 2026
5 СодержаниеУстановка Open Server Panel 6.5.+. Подробное руководство для новичков – Первый запуск на PHP 8.5Что такое

Автор контента

webitproff

Оффлайн

Carbonate Sodium

Последняя авторизация: 04.08.2026 15:17

  • Чем могу помочь?

    Оказываю весь спектр услуг по CMF Cotonti. Разработка открытых и закрытых корпоративных интернет порталов, небольших социальных сетей, торговые площадки, маркетплейсы, биржи фриланса, каталоги товаров оптовых поставщиков, интернет-магазин под заказ, чтобы делать совместные покупки и групповые совместные продажи от имени нескольких продавцов.

  • Разработки на GitHub бесплатно
    • Страница размещена: 14.06.2026 01:41
    • Последнее обновление: 14.06.2026 01:43
    • Язык: