Как сделать липкий сайдбар (Sticky Sidebar) на WordPress

Как сделать липкий сайдбар (Sticky Sidebar) на WordPress

Введение

В этой статье я расскажу, как реализовать «умный» липкий сайдбар, который прилипает к хедеру при прокрутке страницы и возвращается на место при возврате наверх.

Что мы реализуем

  • При прокрутке — сайдбар прилипает к нижней части хедера с отступом 20px
  • При возврате наверх — сайдбар возвращается на своё место
  • Если сайдбар длинный — добавлена прокрутка внутри него с красивым тонким скроллбаром
  • Максимальная высота — ограничена, чтобы не выходить за пределы экрана

JavaScript код

Создаём файл sticky-header.js в папке с JS-файлами темы:

(function() {
    'use strict';

    function initStickyElements() {
        const header = document.getElementById('masthead');
        const sidebar = document.getElementById('secondary');
        
        if (!header) return;

        let headerHeight = header.offsetHeight;
        let sidebarWidth = 0;
        let sidebarLeft = 0;
        let isSidebarSticky = false;

        function updateSidebarDimensions() {
            if (sidebar && !isSidebarSticky) {
                const rect = sidebar.getBoundingClientRect();
                sidebarWidth = rect.width;
                sidebarLeft = rect.left + window.pageXOffset;
            }
        }

        updateSidebarDimensions();

        function handleScroll() {
            const scrollTop = window.pageYOffset;

            if (sidebar) {
                if (scrollTop > headerHeight && !isSidebarSticky) {
                    updateSidebarDimensions();
                    isSidebarSticky = true;
                    sidebar.classList.add('is-sticky');
                    sidebar.style.top = headerHeight + 20 + 'px';
                    sidebar.style.width = sidebarWidth + 'px';
                    sidebar.style.left = sidebarLeft + 'px';
                } else if (scrollTop <= headerHeight && isSidebarSticky) {
                    isSidebarSticky = false;
                    sidebar.classList.remove('is-sticky');
                    sidebar.style.cssText = '';
                }
            }
        }

        let ticking = false;
        window.addEventListener('scroll', function() {
            if (!ticking) {
                requestAnimationFrame(function() {
                    handleScroll();
                    ticking = false;
                });
                ticking = true;
            }
        }, { passive: true });

        handleScroll();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initStickyElements);
    } else {
        initStickyElements();
    }
})();

CSS стили

Добавляем стили для sticky сайдбара:

#secondary.is-sticky {
    position: fixed !important;
    max-height: calc(100vh - 100px);
    overflow-y: auto;
    transition: top 0.3s ease;
}

#secondary.is-sticky::-webkit-scrollbar {
    width: 4px;
}

#secondary.is-sticky::-webkit-scrollbar-thumb {
    background: rgba(99, 102, 241, 0.3);
    border-radius: 4px;
}

Как это работает

1. Инициализация

Скрипт находит хедер и сайдбар по их ID. Сохраняются оригинальные размеры и позиция сайдбара.

2. Обработка скролла

При каждом скролле проверяется позиция страницы. Если прокрутили больше высоты хедера — добавляем класс is-sticky и устанавливаем фиксированную позицию.

3. Оптимизация

Используется requestAnimationFrame для оптимизации — обработчик вызывается не чаще 60 раз в секунду.

Заключение

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