Зафиксировать меню и сайдбар (position: sticky)
В CSS 3 для свойства position появилось новое значение «sticky», которая закрепляет элемент в пределах родительского тега.
class="page"> class="top-panel">Фиксированная панель в пределах родительского тега .page /* CSS */ .top-panel < position: sticky; top: 0; >
Одно из основных преимуществ данного свойства перед position: fixed в том, что вёрстка не рушится, если элементу задать значение «sticky».
Значение «sticky» работает во всех современных браузерах (не работает в Internet Explorer, но поддерживается в Internet Edge).
Закрепить только меню, без шапки
Если при прокрутке вниз, закреплять надо только меню (без шапки), для этого также достаточно указать свойство position: sticky .
class="page"> . class="top-panel">Панель, которая при прокрутке будет закрепляться сверху страницы и возвращаться на исходную позицию при прокрутке в начало страницы
Закрепить сайдбар
Чтобы закрепить сайдбар, для него также достаточно указать свойство position: sticky . При этом, сайдбар будет закреплён только в пределах своего родительского тега, т.е. он не будет вылезать, например, в подвал сайта.
Обновлено: 01 ноября 2020 | История изменений
Комментарии
Авторизуйтесь, чтобы добавлять комментарии
- Вывод нескольких элементов в ряд (Flexbox)
- Различия между float и flex
- Хлебные крошки (Breadcrumbs)
- Прижать футер к низу сайта
- Выровнять дочерние элементы по ширине
- Зафиксировать меню и сайдбар (position: sticky)
- Вертикальное выравнивание
- Порядок элементов (order)
- Разница между «px», «em» и «rem»
- 8 советов вёрстки и настройки email-рассылок
- Переместить объект, не влияя на вёрстку
- Пример использования «box-decoration-break»
Как закрепить меню при скроле?
делаю копию тильдовского сайта на вордпрессе. Возникла сложность. В оригинальном сайте, меню фиксируется к верхней части браузера, при скроллинге. Вот: https://ninjamail.click/ На странице над которой работаю, пока такого нет. Вот: https://page.ninjamail.click/bbd90894-b711-4d53-b1cf-486c29b83971/ Как можно на второй странице сделать точно такой же скроллинг? Не через css fixed, а чтобы меню закреплялось при прокрутке на определённое колличество пикселей, как в первом сайте? Спасибо всем, кто поможет.
Отслеживать
задан 18 авг 2022 в 8:05
5 4 4 бронзовых знака
это в любом случае делается через css fixed, просто свойство добавляется при прокрутке на определённое количество пикселей и убирается при прокрутке обратно
18 авг 2022 в 8:14
@humster_spb как можно сделать чтобы оно появлялось при прокрутке?
Как зафиксировать меню при прокрутке страницы
Для удобства управления сайтом, разработчики часто используют фиксацию меню в верхней части страницы, когда при прокрутке пользователь прокрутил шапку сайта полностью и «дошел» до меню, т.е. верхний край меню совпадает в данный момент с верхним краем видимой части страницы и с этого момента меню должно зафиксироваться в верху и дальнейшая прокрутка страницы продолжается, а меню остается вверху.
Чтобы реализовать фиксацию меню с помощью jQuery, необходимо отслеживать прокрутку страницы и при достижении позиции меню его нужно зафиксировать, а при прокрутке обратно вверх, меню нужно снова вернуть в исходное положение.
Предположим, мы имеем такой html-код:
.header < width: 100%; height: 150px; background: #90dcff; >.menuЭто шапка сайта с логотипом и прочим
Это меню, которое зафиксируется при прокрутке страницы
Какой-то контент 1
Какой-то контент 2
Какой-то контент 3
Какой-то контент 4
Какой-то контент 5
Какой-то контент 6
Какой-то контент 7
Какой-то контент 8
Какой-то контент 9
Какой-то контент 10
Какой-то контент 11
Какой-то контент 12
Какой-то контент 13
Какой-то контент 14
Какой-то контент 15
Какой-то контент 16
Какой-то контент 17
Какой-то контент 18
Какой-то контент 19
Какой-то контент 20
Какой-то контент 21
Какой-то контент 22
Какой-то контент 23
Какой-то контент 24
Какой-то контент 25
Какой-то контент 26
Какой-то контент 27
Какой-то контент 28
Какой-то контент 29
Какой-то контент 30
Какой-то контент 31
Какой-то контент 32
Какой-то контент 33
Какой-то контент 34
Какой-то контент 35
Какой-то контент 36
Какой-то контент 37
Какой-то контент 38
Какой-то контент 39
Какой-то контент 40
Какой-то контент 41
Какой-то контент 42
Какой-то контент 43
Какой-то контент 44
Какой-то контент 45
Какой-то контент 46
Какой-то контент 47
Какой-то контент 48
Какой-то контент 49
Какой-то контент 50
Мой вариант скрипта для фиксации меню при прокрутке страницы с использованием jQuery такой:
$(function() < menu_top = $('.menu').offset().top; // запоминаем положение меню $(window).scroll(function () < // отслеживаем событие прокрутки страницы if ($(window).scrollTop() >menu_top) < // если прокрутка дошла до меню if ($('.menu').css('position') != 'fixed') < // проверяем, если меню еще не зафиксировано $('.menu').css('position','fixed'); // задаем блоку меню свойство position = fixed $('.menu').css('top','0'); // положение в самом верху $('.content').css('margin-top','80px'); // делаем отступ, чтобы контент не "скакал" в момент фиксации меню >> else < // прокрутка страницы обратно вверх достигла место "перехода" меню if ($('.menu').css('position') == 'fixed') < // если меню зафиксировано $('.menu').css('position',''); $('.menu').css('top',''); $('.content').css('margin-top',''); >> >); >);
Посмотреть пример в действии (откроется в новом окне)
Несколько дополнительных пояснений к коду:
- во 2-й строчке я запоминаю положение меню относительно страницы, т.к. при прокрутке после его фиксации это значение будет меняться, а нам нужно запомнить исходное значение, либо вместо переменной menu_top можно использовать конкретное значение, например, в нашем случае 150 (высота шапки перед меню);
- в 5-й и 11-й строках прежде чем устанавливать свойства, я сначала проверяю, зафиксировано меню или нет, чтобы css-свойства не устанавливались множество раз, пока страница прокручивается пользователем;
- вместо установки свойств $(‘.menu’).css можно устанавливать и удалять какой-нибудь класс и соответственно, в строках 5 и 11 проверять наличие этого класса в условиях;
- в 8-й строке при фиксации меню я делаю так же отступ для блока content добавляя margin-top равный высоте меню, т.к. если этого не сделать, меню, поменяв свое свойство position на fixed, перестанет «занимать место» и контент расположиться сразу под шапкой, т.е. «скакнет» вверх и чтобы это компенсировать, я и делаю у контента отступ вверху.
Если у вас есть предложения/замечания, пожалуйста напишите в комментариях.
Создаем фиксированное меню на CSS, jQuery + решение проблемы с якорями

С момента публикации первой версии данной заметки прошло уже несколько лет, но текущая информация все еще актуальна. Просто хочу дополнить ее разбором одной нетипичной и сложной ситуации, с которой на днях столкнулся по фрилансу. Новичкам озвученные здесь приемы точно пригодятся, плюс запишу их для себя, т.к. похожие задачи возникают время от времени.
В статье я не буду вдаваться в подробности всех деталей кода, укажу лишь основные нюансы. Можете скопировать эти примеры и попрактиковаться с ними на своих проектах, ну а полным новичкам — не помешает дополнительно глянуть сервис обучения верстке Interneting is Hard.
В посте представлены такие вопросы:
- Как фиксировать меню при прокрутке страницы (это когда блок навигации «прижимается» к верху экрана). Рассмотрим:
- Простое решение на CSS + HTML.
- Фиксированное меню с jQuery и CSS.
- Прокрутка до ссылки якоря с фиксированным меню — без дополнительных хаков в этом случае не обойтись.
- Мобильное фиксированное меню + ссылки якоря (оригинальная задачка с универсальным решением).
- Плагин Page scroll to id — неплохое меню с якорными ссылками для WordPress.
Фиксированное меню на CSS + HTML
В общем случае при создании простого горизонтального фиксированного меню для сайта вам нужно использовать CSS свойства position:fixed и top:0. Также основному блоку контента придется задать верхний отступ margin-top.
Итак, возьмем простую структуру HTML страницы:
Главная О нас КонтактыКакой-то текст для примера.
В файл стилей CSS добавляете:
.menu { overflow: hidden; background-color: #999; position: fixed; top: 0; width: 100%; } .menu a { float: left; display: block; color: #000; padding: 15px 15px; text-decoration: none; } .content { font-style: italic; width: 40%; margin-top: 60px; margin-left: 10px; }
В результате получится такая картинка:

Ничего оригинального, но главное, что работает. Дабы увидеть эффект фиксированного меню при прокрутке страницы вам нужно будет добавить больше текста в блок контента (чтобы появилась полоса прокрутки).
Основные детали кода выше, как я уже говорил, это position:fixed, top:0 и margin-top: 60px. Верхний отступ может быть другим, если высота меню у вас меньше/больше.
Кстати, если требуется зафиксировать меню внизу страницы, заменяете код на:
. menu { position: fixed; bottom: 0; width: 100%; }
Все то же самое, только вместо top указывается bottom:0. Единственное, нужно будет погуглить как правильно сделать отступ контенту снизу чтобы он тот скрывался за плашкой меню. Решение с margin-bottom:30px; почему-то не сработало.
Фиксированное меню с jQuery и CSS
Второй пример чуть более сложный — с применением библиотеки jQuery. Она встречается на многих сайтах, плюс в большинстве шаблонов WordPress и других CMS подключена изначально. Из Javascript функций здесь используется всего 2, поэтому данное решение можно считать достаточно легким по сравнению с некоторыми другими из интернета. Вот что в итоге должно получиться:
Алгоритм внедрения данного фиксированного меню с jQuery состоит из трех шагов. Первым делом добавляем HTML код:
Если вы хотите внедрить данный метод на уже готовое собственное меню, тут 2 пути: либо в CSS и JS ниже подставляете свои стили, либо подгоняете имеющийся HTML под вариант сверху.
В стилях размещаете следующие строки:
.nav-container{ background: url('images/nav_bg.jpg') repeat-x 0 0;} .f-nav{ z-index: 9999; position: fixed; left: 0; top: 0; width: 100%;} .nav { height: 42px;} .nav ul { list-style: none; } .nav ul li{float: left; margin-top: 6px; padding: 6px; border-right: 1px solid #ACACAC;} .nav ul li:first-child{ padding-left: 0;} .nav ul li a { } .nav ul li a:hover{ text-decoration: underline;}
Кроме непосредственно фиксации меню при прокрутке есть CSS для размещение ссылок в одну строку.
jQuery("document").ready(function($){ var nav = $('.nav-container'); $(window).scroll(function () { if ($(this).scrollTop() > 136) { nav.addClass("f-nav"); } else { nav.removeClass("f-nav"); } }); });
Логика работы функций следующая — когда пользователь находится или прокручивает страницу ниже 136 пикселей сверху, то для меню добавляется класс f-nav, а в нем прописаны знакомые нам position:fixed и top:0.
Значение в 136 пикселей можно менять в зависимости от вашего дизайна. Кроме того, если вы интегрируете данный пример в свое готовое горизонтальное фиксированное меню на сайте, то указывайте соответствующие значения классов в JS и CSS. Если у вас возникли какие-то нюансы с реализацией кода, загляните в комментарии к оригинальной статье — там есть парочка подсказок.
Напоследок предлагаю ознакомиться с еще одним вариантом реализации нашей задачи. Не буду особо детализировать его, просто размещаю вставку из онлайн редактора кода Codepen.
Прокрутка до якоря с фиксированным меню
Для начала пару слов о самой задаче. Допустим у вас есть сайт, где вы решили фиксировать меню при прокрутке. При этом в навигации или тексте используются так называемые якоря (Anchor). При переходе по этим ссылкам экран страницы автоматически перемещается к соответствующим местам на странице (где расположен якорь). Однако в таком случае часть контента закрывается блоком меню.
Данная ситуация чаще всего возникает в лендингах. На скриншоте проблема заметна более наглядно:

На StackOverflow найдено два решения задачи, которые отличаются лишь CSS.
Чтобы создать якорь с отступом первым делом добавим ему определенный стиль, например, anchor:
Some text
Some text
Далее для него в стилях прописываете:
.anchor{ display:block; height:55px; margin-top:-55px; visibility:hidden; }
Здесь 55 пикселей — высота меню + отступ, которые нужны чтобы текст контента был виден. Указывайте значения, подходящие вашему сайту. В работе я применял именно этот вариант.
Альтернативный метод предлагает реализацию через padding, там вообще получается одна строка кода:
.anchor { padding-top: 90px; }
В дополнение предлагаю глянуть эту заметку где автор привел сразу 5 разных решений как правильно использовать якоря с отступом для горизонтального фиксированного меню при прокрутке страницы: через псевдоэлементы, негативные отступы и т.п.
Динамическое фиксированное меню + якоря содержания (в мобильной версии)
Уже по заголовку видно, что ситуация у меня возникла не простая. Возможно, и существует какое-то более изящное решение, но за день поисков ничего лучше найти не удалось. Оно еще и работает в отличии от остальных!
Пару слов о самой задаче. Вот как выглядит мое меню:

- Во-первых, в начале статьи с помощью плагина Easy Table of Contents автоматически выводится содержимое той или иной публикации. При клике на соответствующие ссылки вы попадаете в нужное место статьи. ВАЖНО! Если у вас установлен этот же модуль, то там для мобильных версий есть специальная настройка и ничего дополнительно внедрять НЕ нужно.
- Во-вторых, на мобильных устройствах при прокрутке экрана появляется специальное меню с темным фоном, которое фиксируется сверху экрана.
Я перепробовал много разных вариантов: и рассмотренный выше сдвиг якоря вниз страницы с помощью CSS, и добавление специальной переменной, срабатывающей при клике на содержимое Easy Table of Contents, но безрезультатно.
Сложность была в том, что оба действия (якорь и появление мобильного меню) были привязаны к обработке события scroll. Я пытался их разделить, но переход на якорные ссылки все равно влиял на scroll. Читал, что можно сделать подобные якоря без перегрузки страницы с помощью hashchange, но в эту тему не сильно вникал (хотя в примере ниже эта фишка присутствует).
В итоге мне помогла эта запись на Stackoverflow. Ниже представлена версия с jQuery для более гладкого перехода. Визуально решение позволяет после перехода на якорь “отмотать” назад содержимое экрана чтобы меню его не перекрывало.
Вот работающий финальный код + возможность посмотреть результат в реальном времени:
Продублирую на всякий случай его в статье. По HTML ничего особенного – сначала идет меню, а затем 5 разных блоков DIV.
Jump to target 2Jump to target 3Jump to target 4Jump to target 5Jump to target 1
Стили тоже вполне стандартные – каждый DIV занимает всю высоту видимой области экрана + прописываются детали фиксированного меню.
body { padding: 0; margin: 50px 0 0; font-family: "Arial"; font-size: 1em; } a { color: #333; } #fixed { position: fixed; height: 50px; line-height: 50px; background: #000; top: 0; left: 0; right: 0; color: #fff; padding-left: 5px; } #targets div { height: 100vh; padding: 10px; color: #333; } #target-1 { background: #888; } #target-2 { background: #999; } #target-3 { background: #AAA; } #target-4 { background: #BBB; } #target-5 { background: #CCC; }
Ну, и в завершение – JavaScript. Тут, признаться я мало что могу объяснить, т.к. слабо понимаю, что конкретно происходит. Если бы не комментарии разработчика, то все это походило бы на какую-то магию.
(function(document, history, location) { var HISTORY_SUPPORT = !!(history && history.pushState); var anchorScrolls = { ANCHOR_REGEX: /^#[^ ]+$/, OFFSET_HEIGHT_PX: 50, /** * Establish events, and fix initial scroll position if a hash is provided. */ init: function() { this.scrollToCurrent(); $(window).on('hashchange', $.proxy(this, 'scrollToCurrent')); $('body').on('click', 'a', $.proxy(this, 'delegateAnchors')); }, /** * Return the offset amount to deduct from the normal scroll position. * Modify as appropriate to allow for dynamic calculations */ getFixedOffset: function() { return this.OFFSET_HEIGHT_PX; }, /** * If the provided href is an anchor which resolves to an element on the * page, scroll to it. * @param href * @return - Was the href an anchor. */ scrollIfAnchor: function(href, pushToHistory) { var match, anchorOffset; if(!this.ANCHOR_REGEX.test(href)) { return false; } match = document.getElementById(href.slice(1)); if(match) { anchorOffset = $(match).offset().top - this.getFixedOffset(); $('html, body').animate({ scrollTop: anchorOffset}); // Add the state to history as-per normal anchor links if(HISTORY_SUPPORT && pushToHistory) { history.pushState({}, document.title, location.pathname + href); } } return !!match; }, /** * Attempt to scroll to the current location's hash. */ scrollToCurrent: function(e) { if(this.scrollIfAnchor(window.location.hash) && e) { e.preventDefault(); } }, /** * If the click event's target was an anchor, fix the scroll position. */ delegateAnchors: function(e) { var elem = e.target; if(this.scrollIfAnchor(elem.getAttribute('href'), true)) { e.preventDefault(); } } }; $(document).ready($.proxy(anchorScrolls, 'init')); })(window.document, window.history, window.location);
У меня лично код сработал без каких-либо дополнительных правок и манипуляций – я просто добавил его в файл скриптов своего шаблона script.js. Важно заменить в коде переменную OFFSET_HEIGHT_PX, в которой задается высота вашего меню (т.е. итоговый отступ сверху экрана).
Плагин Page scroll to id

Кстати, если вы работаете с WordPress, то вас может заинтересовать этот модуль. Нашел его чуть раньше, и он частично перекликается с текущей задачей. Плагин внедряет более плавную и красивую анимацию перехода по ссылкам якорям и при этом обладает некоторыми приятными фишками:
- вертикальным и горизонтальным скроллингом;
- разными настройками анимации;
- поддержкой переходов по ссылкам на другие страницы;
- подсветкой ссылок, заданием отступов, длительности перехода и т.п.;
Вот как выглядит пример меню:

Думаю, Page scroll to id будет полезен, если вам надо сделать навигацию на одностраничном лендинге, а базовый шаблон не обладает подобной опцией (либо она ограничена в настройках).
Если знаете еще какие-то интересные сниппеты или есть, что добавить по теме, пишем в комментариях.
- CodePen — бесплатный онлайн редактор кода (HTML, CSS, JS)
- Обнуление CSS стилей — зачем это делать, типы CSS Reset файлов
- Изучаем CSS Grid Layout и Flexbox на практике (20+ сервисов и полезных материалов)
- Пустой :empty CSS селектор — определение, примеры использования
- Как выглядит сайт на разных устройствах с iOS – проверка верстки на iPhone, iPad, Mac