Sidebar layout
Макет «фиксированный сайдбар + растягивающийся контент» — основа для дашбордов, CMS и admin-панелей.
Задача
Нужна страница с левым навигационным сайдбаром фиксированной ширины и основной областью контента, занимающей оставшееся пространство. На мобильных сайдбар должен скрываться.
Решение
<div class="app">
<aside class="sidebar" id="sidebar">
<div class="sidebar__logo">MyApp</div>
<nav class="sidebar__nav">
<a class="sidebar__link active" href="#">Дашборд</a>
<a class="sidebar__link" href="#">Пользователи</a>
<a class="sidebar__link" href="#">Настройки</a>
</nav>
</aside>
<div class="content-area">
<header class="topbar">
<button class="topbar__toggle" id="sidebarToggle" aria-label="Открыть меню">
☰
</button>
<h1 class="topbar__title">Дашборд</h1>
</header>
<main class="main">
<p>Основной контент</p>
</main>
</div>
</div>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
.app {
display: flex;
min-height: 100vh;
}
/* Сайдбар */
.sidebar {
width: 240px;
flex-shrink: 0;
background: #1e293b;
color: #fff;
display: flex;
flex-direction: column;
transition: transform 0.3s ease;
}
.sidebar__logo {
padding: 20px 24px;
font-size: 1.2rem;
font-weight: 700;
border-bottom: 1px solid #334155;
}
.sidebar__nav { display: flex; flex-direction: column; padding: 16px 0; }
.sidebar__link {
padding: 10px 24px;
color: #94a3b8;
text-decoration: none;
transition: background 0.15s, color 0.15s;
}
.sidebar__link:hover,
.sidebar__link.active { background: #334155; color: #fff; }
/* Контентная область */
.content-area {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0; /* важно для flex + overflow */
}
.topbar {
display: flex;
align-items: center;
gap: 16px;
padding: 0 24px;
height: 60px;
background: #fff;
border-bottom: 1px solid #e2e8f0;
}
.topbar__toggle { display: none; background: none; border: none; font-size: 1.4rem; cursor: pointer; }
.main { padding: 24px; flex: 1; }
/* Адаптив */
@media (max-width: 768px) {
.sidebar {
position: fixed;
inset: 0 auto 0 0;
z-index: 200;
transform: translateX(-100%);
}
.sidebar.open() { transform: translateX(0); }
.topbar__toggle { display: block; }
}
const toggle = document.getElementById('sidebarToggle');
const sidebar = document.getElementById('sidebar');
toggle.addEventListener('click', () => {
sidebar.classList.toggle('open');
});
// Закрыть при клике на overlay
document.addEventListener('click', (e) => {
if (!sidebar.contains(e.target) && !toggle.contains(e.target)) {
sidebar.classList.remove('open');
}
});
Ключевые моменты
flex: 1на.content-area— занимает всё оставшееся место;flex-shrink: 0на.sidebar— не сжимается.min-width: 0на flex-элементе с контентом — предотвращает выход длинного текста за пределы.- На мобильных сайдбар —
position: fixedсtransformдля плавного слайда; JS только добавляет/убирает класс. - Закрытие по клику вне сайдбара — стандартное UX-поведение для мобильных.
Варианты
- Сайдбар справа: поменяй порядок flex-элементов или используй
flex-direction: row-reverse. - Сворачиваемый сайдбар (только иконки): анимируй
widthмежду240pxи60px.