Как сделать липкую навигационную панель (sticky header) на WordPress

К чему стремимся
Мы хотим, чтобы навигационная панель и поисковый элемент «прилипали» к верхней части окна только после того, как пользователь прокрутит страницу до определённой точки. В этом руководстве показан подход с jQuery (работает при наличии jQuery), а также даны альтернативы и рекомендации для продакшена.
Основные варианты реализации
- Быстрое решение: jQuery — вычисляем смещение, вешаем обработчик scroll, переключаем position: fixed.
- Современная CSS-альтернатива: position: sticky — проще, но требует подходящей структуры и поддержки браузеров.
- Проактивный вариант: IntersectionObserver — более оптимально для производительности и точнее управляет состоянием.
HTML
Откройте header.php вашей темы и найдите блок навигации. В стандартной теме Twenty Eleven это:
Добавьте контейнер вокруг всей NAV-секции:
Переместите туда форму поиска. Найдите строку
и вставьте её внутрь навигации. Удалите остальные вхождения этой функции в header.php.
Если после правки форма поиска всё ещё отображается в верхнем правом углу, значит ей задано абсолютное позиционирование в CSS — мы это исправим в следующем разделе.
CSS
Откройте основной style.css и найдите секцию, отвечающую за форму поиска:
#branding #searchform { ... }Замените содержимое на:
#branding #searchform { float:left; background:white; margin:7px ; }Можете подправить цвет, отступы или float (например, float:right если хотите, чтобы поиск был справа). В теме Twenty Eleven поиск может расширяться при клике — это отдельно от этой инструкции.
jQuery: почему и как
Почему jQuery: CSS фиксированного позиционирования нельзя динамически включать/выключать в зависимости от текущей позиции элемента без внешнего скрипта, если элемент не является начальным верхним элементом документа. jQuery позволяет определить момент, когда пользователь прокрутил страницу мимо исходного расположения меню, и применить position: fixed.
Добавьте jQuery в тему, если он ещё не подключён. Два варианта:
- Регистрировать и подключать через functions.php (загружается в режиме noConflict, используйте jQuery):
- Вставить напрямую в head (можно использовать $ напрямую):
В следующем фрагменте предполагается второй способ (доступен $). Поместите скрипт в конце header.php, перед
Объяснение алгоритма:
- Скрипт запоминает текущее вертикальное смещение элемента навигации.
- На каждое событие прокрутки проверяется положение окна относительно сохранённой точки.
- Если окно прокручено ниже — навигация становится фиксированной (position: fixed).
- Если пользователь прокручивает вверх выше исходной точки — состояние возвращается к static.
Обратите внимание на два момента:
В строке расчёта используется +288. Это фиктивная корректировка, чтобы избежать преждевременного переключения в конкретной теме. В других темах этот сдвиг может не потребоваться — лучше вычислять динамически или добавлять отступ-«якорь».
Чтобы предотвратить изменение ширины навигации при переходе в фиксированное состояние, задайте в CSS конкретную ширину, например замените 100% на 1000px (или используйте вычисление ширины через JS). В примере автора используется style.css, строка ~550.
Готово
После этих правок навигационная панель будет «прилипать» к верху экрана при прокрутке дальше заданной точки. Тестируйте на разных размерах экрана.
Альтернативные подходы и улучшения
1) CSS: position: sticky (проще, но с ограничениями)
Пример:
.nav { position: -webkit-sticky; position: sticky; top: 0; z-index: 1000; }Когда использовать: когда навигация расположена в потоке документа и вы хотите, чтобы элемент «прилипал» к родительскому контейнеру. Ограничения: родительский контейнер не должен иметь overflow: hidden/auto, и поведение может отличаться в старых браузерах.
2) IntersectionObserver (лучше для производительности)
Короткий пример:
const sentinel = document.querySelector('#sentinel');
const nav = document.querySelector('#access');
const io = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (!entry.isIntersecting) {
nav.classList.add('is-sticky');
} else {
nav.classList.remove('is-sticky');
}
});
});
io.observe(sentinel);Где #sentinel — невидимый элемент в документе, расположенный там, где нужно переключать состояние. IntersectionObserver уменьшает нагрузку по сравнению с постоянной обработкой scroll.
3) Клонирование элемента и фиксирование клона
Иногда проще клонировать навигацию, вставить клон в
и показывать/прятать его при прокрутке; это избавляет от проблем с изменением ширины и компоновкой оригинального блока.4) Плавные переходы и компенсатор высоты
При смене position элемент может «прыгать». Решение: при фиксировании добавлять placeholder с той же высотой, чтобы сохранить поток документа, либо плавно анимировать top и opacity.
Когда это не подходит
- Если у вас очень сложная адаптивная верстка, где ширина навигации динамична и зависит от контента, фиксированное позиционирование может ломать макет.
- На слабых мобильных устройствах постоянная обработка scroll ухудшает производительность — используйте passive listeners или IntersectionObserver.
- Если навигация содержит интерактивные элементы (формы, выпадающие меню), убедитесь, что фиксированная панель не перекрывает другие элементы и доступна с клавиатуры.
Критерии приёмки
- Навигация становится фиксированной точно после заданной точки прокрутки без визуальных «прыжков».
- Не нарушается доступность: элементы в навигации доступны клавиатурой и экранными читалками.
- Отображение корректно на основных размерах экранов (desktop, tablet, mobile).
- Отсутствие резкого падения производительности при прокрутке.
- Нет перекрытия важного контента без отступа (body или основного контейнера).
Чек-листы по ролям
Разработчик:
- Перенёс форму поиска в nav и обновил CSS.
- Подключил jQuery или написал альтернативу на чистом JS.
- Обработал изменение ширины при фиксации (через CSS или JS).
- Добавил placeholder/компенсатор для предотвращения сдвига содержимого.
Дизайнер:
- Согласовал внешний вид фиксированной панели: фон, тень, z-index.
- Проверил контраст текста и кнопок с учётом WCAG.
- Убедился, что элементы меню не перекрывают важный контент.
QA / Тестировщик:
- Протестировал на популярных браузерах и мобильных устройствах.
- Проверил keyboard navigation и фокус на интерактивных элементах.
- Проверил поведение при изменении размера окна.
Ментальные модели и эвристики
- Якорь: думайте о том, что навигация имеет «якорную» позицию в документе — точку, после которой она должна прилипать.
- Placeholder: всегда планируйте, как сохранить поток документа при смене position.
- Производительность: минимизируйте работу в обработчике scroll, используйте throttle/debounce или IntersectionObserver.
Советы по доступности и UX
- При фиксации панели убедитесь, что она не закрывает заголовки или формы; добавьте соответствующий отступ у основного контента.
- Давайте фиксированной панели явный z-index и тень, чтобы она выглядела как отдельный слой.
- При больших панелях на мобильных — рассмотрите вариант скрывать панель при прокрутке вниз и показывать при прокрутке вверх.
Возможные проблемы и способы их устранения
- Прыжок контента при фиксации: добавить placeholder с той же высотой.
- Изменение ширины: вычислять и записывать width навигации при фиксации через JS.
- Преждевременное срабатывание: избегайте «жёстких» калибровочных значений (+288), используйте точное вычисление позиции или sentinel.
- Низкая производительность: используйте passive listeners, throttle/debounce или IntersectionObserver.
Примеры кода — краткий набор шаблонов
- CSS sticky:
.header { position: sticky; top: 0; z-index: 999; }- IntersectionObserver — пример, где #sentinel — невидимый блок, размещённый выше навигации:
const nav = document.querySelector('#access');
const sentinel = document.createElement('div');
sentinel.id = 'sentinel';
document.body.insertBefore(sentinel, document.body.firstChild);
const observer = new IntersectionObserver(([e]) => {
nav.classList.toggle('is-sticky', e.intersectionRatio < 1);
});
observer.observe(sentinel);- jQuery (исходный, адаптированный):
(Сохраняйте оригинальные id/классы и при необходимости корректируйте селекторы.)
Тестовые случаи и приёмка
- Прокрутка вниз за точку — панель фиксируется.
- Прокрутка вверх до точки — панель возвращается в поток.
- Проверка на ширине 320px, 768px, 1024px и desktop.
- Проверка клавиатурной навигации: Tab и Enter работают корректно.
- Проверка на мобильном устройстве с медленным CPU: отсутствуют подтормаживания.
Итог
Реализация «липкой» навигации на WordPress относительно проста: перемещаем форму поиска в nav, меняем CSS, добавляем скрипт, который отслеживает прокрутку и переключает position. Для продакшн-решения рассмотрите IntersectionObserver или CSS position: sticky, обработайте доступность и учтите производительность.
Важно: не используйте жёсткие «магические» числа без тестирования в вашей теме — лучше вычислять положение динамически или использовать sentinel-подход.
Короткая методика внедрения (mini-methodology):
- Перенести/обозначить элемент навигации и форму поиска.
- Убедиться, что CSS не содержит absolute-позиционирования, мешающего интеграции.
- Выбрать метод: CSS sticky / jQuery / IntersectionObserver.
- Добавить placeholder/компенсатор и тестировать на всех устройствах.
Если вы хотите, я могу подготовить вариант кода именно для вашей темы: пришлите HTML header.php и текущие стили для #access и #branding.
Контакты и дополнительные материалы
Если возникнут проблемы — опубликуйте ссылку на сайт, чтобы можно было посмотреть вживую. Также изучите документацию по position: sticky и IntersectionObserver для полного понимания поведения в разных браузерах.
Похожие материалы
Тёмная тема в Gmail: как включить и улучшить
Как отменить подписки в App Store
Как связаться с Instagram — номера и отчёты
FORMULATEXT в Excel: аудит и проверка формул
Поддержка Gmail: справка, форум и практические советы