Headroom.js позволяет управлять поведением шапки сайта при скролле, автоматически скрывая её при прокрутке вниз и показывая при прокрутке вверх. Для интеграции с гамбургер-меню потребуется создать отдельный контейнер для навигации и управлять его видимостью через CSS-классы и события Headroom.
<header class="header">
<div class="logo">Логотип</div>
<button class="hamburger" id="hamburger-toggle">☰</button>
<nav class="nav" id="nav-menu">
<ul>
<li><a href="#home">Главная</a></li>
<li><a href="#about">О нас</a></li>
<li><a href="#services">Услуги</a></li>
<li><a href="#contact">Контакты</a></li>
</ul>
</nav>
</header>
Подключение Headroom.js:
<script src="https://unpkg.com/headroom.js@0.12.0/dist/headroom.min.js"></script>
Инициализация скрипта:
const header = document.querySelector(".header");
const headroom = new Headroom(header, {
tolerance: {
up: 10,
down: 20
},
offset: 50,
classes: {
initial: "header--initial",
pinned: "header--pinned",
unpinned: "header--unpinned",
top: "header--top",
notTop: "header--not-top",
bottom: "header--bottom",
notBottom: "header--not-bottom"
}
});
headroom.init();
Для корректной работы меню важно синхронизировать его состояние с поведением шапки. Если меню открыто и пользователь скроллит вниз, шапка должна скрываться, но меню оставаться видимым либо закрываться, в зависимости от UX-дизайна.
const hamburgerToggle = document.getElementById("hamburger-toggle");
const navMenu = document.getElementById("nav-menu");
hamburgerToggle.addEventListener("click", () => {
navMenu.classList.toggle("nav--active");
hamburgerToggle.classList.toggle("is-active");
});
// Закрытие меню при прокрутке вниз
headroom.on("unpin", () => {
if (navMenu.classList.contains("nav--active")) {
navMenu.classList.remove("nav--active");
hamburgerToggle.classList.remove("is-active");
}
});
Headroom.js работает через добавление и удаление CSS-классов. Для комбинации с гамбургер-меню рекомендуется использовать переходы и трансформации, чтобы движение шапки и открытие меню выглядело естественно.
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #ffffff;
z-index: 1000;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.header--unpinned {
transform: translateY(-100%);
}
.header--pinned {
transform: translateY(0);
}
.nav {
display: none;
position: absolute;
top: 100%;
right: 0;
background: #ffffff;
width: 200px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.nav--active {
display: block;
transform: translateY(0);
opacity: 1;
}
.hamburger.is-active {
transform: rotate(90deg);
transition: transform 0.3s ease;
}
Для мобильных экранов часто используют расширенный подход: шапка остаётся закреплённой, но гамбургер-меню занимает весь экран при открытии. В этом случае Headroom.js лучше отключать при открытом меню, чтобы не конфликтовать с UX.
headroom.on("pin", () => {
if (window.innerWidth <= 768 && navMenu.classList.contains("nav--active")) {
headroom.unpin();
}
});
Для плавного появления элементов меню можно добавить последовательную анимацию с задержкой через CSS:
.nav ul li {
opacity: 0;
transform: translateY(-10px);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.nav--active ul li {
opacity: 1;
transform: translateY(0);
}
.nav--active ul li:nth-child(1) { transition-delay: 0.05s; }
.nav--active ul li:nth-child(2) { transition-delay: 0.10s; }
.nav--active ul li:nth-child(3) { transition-delay: 0.15s; }
.nav--active ul li:nth-child(4) { transition-delay: 0.20s; }
Для улучшения UX важно закрывать меню, если пользователь нажимает вне блока навигации:
document.addEventListener("click", (event) => {
if (!navMenu.contains(event.target) && !hamburgerToggle.contains(event.target)) {
navMenu.classList.remove("nav--active");
hamburgerToggle.classList.remove("is-active");
}
});
Можно задавать динамические параметры offset и
tolerance, чтобы учитывать размер шапки с меню:
headroom.offset = navMenu.offsetHeight + 20;
headroom.tolerance = { up: 5, down: 15 };
Такой подход гарантирует, что шапка будет корректно скрываться даже при расширенном меню, сохраняя плавность анимации и предсказуемое поведение на всех устройствах.