Как сделать эффект залипания при прокручивании страницы на блоках навигации, меню и любых других без дёрганий и анимации. Используем обычный CSS без JS, а также рассмотрим вариант на jQuery и нативный ванильный JavaScript 
- Используем CSS — position:sticky
 - Как сделать залипающую шапку
 - Как сделать залипающий подвал
 - Используем Sticky JS
 - Как сделать фиксированное меню в шапке
 - HTML
 - JavaScript
 - CSS
 - Фиксированный виджет в сайдбаре
 - Q2W3 Fixed Widget — плагин WordPress для фиксации виджета сбоку
 - Как пользоваться
 - Как сделать залипающий виджет, который не налезает на низ сайта
 - HTML
 - JavaScript
 - Делаем залипание в сайдбаре вручную, вариант №2
 - Предварительная подготовка
 - Код HTML
 - Код Javascript
 - В заключение
 
Используем CSS — position:sticky
Использование CSS-свойства position:sticky с целью достичь эффекта залипания блока внутри родительского контейнера — самый эффективный, простой и нативный способ, который работает во всех браузерах (кроме Internet Explorer, которым уже почти никто не пользуется).
Как сделать залипающую шапку
<style>
.header{position:-webkit-sticky; position:sticky; top:0;}
</style>
<main class="main">
  <header class="header">HEADER</header>
  <article class="content">MAIN CONTENT</article>
  <footer class="footer">FOOTER</footer>
</main>
Посмотреть, как залипает header, и даже покрутить код можно на Codepen
Как сделать залипающий подвал
<style>
.footer{position:-webkit-sticky; position:sticky; bottom:0;}
</style>
<main class="main">
  <header class="header">HEADER</header>
  <article class="content">MAIN CONTENT</article>
  <footer class="footer">FOOTER</footer>
</main>
Посмотреть, как работает залипающий footer — Codepen
Используем Sticky JS
- Качаете файл https://raw.githubusercontent.com/rgalus/sticky-js/master/dist/sticky.min.js
 - Сохраняете его на хостинге, где расположен сайт, и подключаете его в шаблоне:
<script src="/путь_до_файла/sticky.min.js"></script>
 - Инициализируете скрипт:
<script> var sticky = new Sticky('.selector'); </script>Здесь
.selector— это jQuery селектор блока, который должен залипать при прокрутке. - 
Если нужно, чтобы залипающий блок останавливался, когда заканчивается родительский контейнер, укажите в родительском контейнере атрибут
data-sticky-container 
Пример HTML:
<div class="row" data-sticky-container>
  <div class="col-2 columns">
    <img src="http://placehold.it/250x250" class="sticky" data-margin-top="20" data-sticky-for="1023" data-sticky-class="is-sticky">
  </div>
  <div class="col-8 columns">
    <h1>Sticky-js</h1>
    <p>Lorem ipsum.....</p>
  </div>
  <div class="col-2 columns">
    <img src="http://placehold.it/250x250" class="sticky" data-margin-top="20" data-sticky-for="1023" data-sticky-class="is-sticky">
  </div>
</div>
<script src="sticky.min.js"></script>
<script>
  var sticky = new Sticky('.sticky');
</script>
Этого кода вполне достаточно, чтобы покрыть большинство требований на залипающее меню, шапку сайта или виджет в сайдбаре сбоку. Если этот вариант не помог, ниже пойдут примеры, в которых наглядно объясняется принцип и механизм работы залипания с готовыми решениями.
Как сделать фиксированное меню в шапке
Всё очень просто. Всё будет основываться на том, где находится скролл на текущий момент относительно нашего меню
- Если скролл ниже, чем верхушка блока нашего меню, включаем залипание
 - Иначе отключаем залипание
 
Вот и вся логика.
Можете проверить, как работает
HTML
HTML будет представлять собой что-то навроде
<div id="nav">...Тут содержание навигации...</div>
JavaScript
В Javascript будем определять нашу логику
jQuery(document).ready(function($) {
  var
    $window = $(window), // Основное окно
    $target = $("#nav"), // Блок, который нужно фиксировать при прокрутке
    $h = $target.offset().top; // Определяем координаты верха нужного блока (например, с навигацией или виджетом, который надо фиксировать)
  $window.on('scroll', function() {
    // Как далеко вниз прокрутили страницу
    var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    // Если прокрутили скролл ниже макушки нужного блока, включаем ему фиксацию
    if (scrollTop > $h) {
      $target.addClass("sheensay_fixed");
    // Иначе возвращаем всё назад
    } else {     
      $target.removeClass("sheensay_fixed");
    }
  });
});
Если не хотите включать залипание для мобильных браузеров, вам пригодится такой код:
 // Определяем мобильный браузер
 function MobileDetect() {
   var UA = navigator.userAgent.toLowerCase();
   return (/android|webos|iris|bolt|mobile|iphone|ipad|ipod|iemobile|blackberry|windows phone|opera mobi|opera mini/i.test(UA)) ? true : false;
 }
 jQuery(document).ready(function($) {
   // Если браузер не мобильный, работаем
   if (!MobileDetect()) {
     var
       $window = $(window), // Основное окно
       $target = $("#nav"), // Блок, который нужно фиксировать при прокрутке
       $h = $target.offset().top; // Определяем координаты верха нужного блока (например, с навигацией или виджетом, который надо фиксировать)
     $window.on('scroll', function() {
       // Как далеко вниз прокрутили страницу
       var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
       // Если прокрутили скролл ниже макушки нужного блока, включаем ему фиксацию
       if (scrollTop > $h) {
         $target.addClass("sheensay_fixed");
         // Иначе возвращаем всё назад
       } else {
         $target.removeClass("sheensay_fixed");
       }
     });
   }
 });
CSS
В CSS определяется класс, которым фиксируем меню
.sheensay_fixed {
   position: fixed !important;
   top: 0 !important;
   margin-left: -100%;
   padding-left: 100%;
   background: rgba(255, 0, 0, 0.1);
}
Строки 4, 5, 6 не обязательны, по могут помочь при горизонтальном выравнивании и создании эффекта полосы на всю ширину экрана.
Прозрачность регулируется в  background: rgba(255, 0, 0, 0.1);, а именно в последнем параметре 0.1, варируется от 0 (прозрачный) до 1 (непрозрачный), это аналог css свойства opacity
Фиксированный виджет в сайдбаре
Для больших статей дубль содержания статьи в сайдбаре в роли виджета очень удобен, видно всё содержание в категоризованном формате. Также, там можно размещать рекламу или другие виджеты с похожими статьями или чем-то подобным.
Ниже будет приведено несколько вариантов, как сделать залипающий виджет в сайдбаре сбоку от основной статьи.
Q2W3 Fixed Widget — плагин WordPress для фиксации виджета сбоку
Q2W3 Fixed Widget — это Вордпресс-плагин, который позволяет при прокрутке страницы залипать виджетам, расположенным сбоку в сайдбаре.

Скачать Q2W3 Fixed Widget из официального репозитория WordPress
Как пользоваться
Вы просто устанавливаете плагин и активируете его. Теперь любой виджет в сайдбаре будет иметь такую галочку
У каждого виджета появляется возможность залипания
Как сделать залипающий виджет, который не налезает на низ сайта
Ниже показан вариант, который в основе содержит принцип фиксированной навигации из 1 пункта.
Задача — для определённого виджета сделать залипание, но так, чтобы он не налезал на подвал сайта.
Принцип прост: мы высчитываем несколько переменных, а именно: 
- Координату Y верха виджета
 - Высоту виджета
 - Координату Y подвала сайта
 
Далее, на событии window.scroll мы считаем текущие координаты верха браузера.
- Если координата верха браузера выше координаты верха виджета, ничего не делаем, снимаем все эффекты
 - Если прокрутили ниже верха виджета, включаем залипание
 - Если прокрутили ниже координаты подвала минус высота виджета или, проще говоря, начали налезать на подвал, отключаем залипание, включаем прописку над подвалом
 
HTML
<body>
  <div class="header">Header</div>
  <div class="body clearfix">
    <div class="main">
... Основное содержимое ...
    </div>
    <div class="sidebar">
... Содержимое сайдбара ...
      <div class=widget>
... Содержимое виджета ...
</div>
    </div>
  </div>
  <div class="footer">Подвал</div>
</body>
JavaScript
Перед скриптом необходимо загрузить jQuery
jQuery( document ).ready(function( $ ) {
	var
			$window = $( window ), // Основное окно
			$target = $( "#fixed_scroll" ), // Блок, который нужно фиксировать при прокрутке
			$bottom = $( '#footer' ), // Нижний блок, за который нельзя заходить
			$top = $target.offset().top, // Определяем координаты верха нужного блока 
			$height = $top + $target.outerHeight(), // Определяем координаты низа $target блока // Блок, который нужно фиксировать при прокрутке
			$bottom = $bottom.offset().top; // Определяем координаты низа нижнего блока // Нижний блок, за который нельзя заходить
	$window.on( 'scroll', function () {
		// Как далеко вниз прокрутили страницу
		var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
		// Если прокрутили скролл ниже макушки нужного блока, но не ниже нижнего блока, включаем ему фиксацию
		if ( scrollTop > $top && scrollTop + $height < $bottom ) {
			$target.css( {
				position : 'fixed',
				top : '0px',
				//width : '1%', // Может пригодиться, если блок не имеет чёткого width
			} );
			// Докрутили до низа
		} else if ( scrollTop > $top && scrollTop + $height > $bottom ) {
			// Координата верха: куда нельзя заходить - минус верх - минус высота блока рекламы
			var top = $bottom - scrollTop - $height;
			$target.css( {
				position : 'fixed',
				top : top,
			} );
		}
		// Иначе возвращаем всё назад
		else {
			$target.attr( 'style', '' );
		}
	} );
});
Если код выше не помогает, проверьте, не использует ли какой-либо из родительских контейнеров css-свойство
backface-visibility: hidden;. Если так, то можно заменить код$target.css( {position : 'fixed',top : 0,} );на
$target.css( {position : 'absolute',top : $window.scrollTop(),} );
Делаем залипание в сайдбаре вручную, вариант №2
Этот вариант сугубо кастомный, основан на специальном PHP-классе Kama_Contents, реализацию можно увидеть справа в боковой колонке. Выложу код и логику, пригодится.
Предварительная подготовка
Для начала, вам нужно иметь содержание статьи. Также, необходимо подключить jQuery
- Создаём обёртку под будущую копию содержания статьи
 - Клонируем содержание статьи и добавляем её внутрь обёртки, подчищаем код
 - Отслеживаем координаты верха виджета.
 - Если прокрутили ниже этой верхушки, но не достигли конца статьи, фиксируем меню
 - Если достигли конца статьи, скрываем виджет меню
 - В остальных случаях оставляем как и было изначально
 
Код HTML
Для примера возьмём содержание этой страницы
<div class="kc__wrap"> <div id="kcmenu" class="kc-title kc_title">Содержание</div> <ul class="contents"> <li class="top"><a href="#kak-sdelat-fiksirovannoe-menyu-v-shapke">Как сделать фиксированное меню в шапке</a></li> <li class="sub sub_1"><a href="#html">HTML</a></li> <li class="sub sub_1"><a href="#javascript">JavaScript</a></li> <li class="top"><a href="#fiksirovannoe-soderzhanie-stati-v-vidzhete-v-saydbare">Фиксированное содержание статьи в виджете в сайдбаре</a></li> <li class="sub sub_1"><a href="#predvaritelnaya-podgotovka">Предварительная подготовка</a></li> <li class="sub sub_1"><a href="#logika">Логика</a></li> <li class="sub sub_1"><a href="#kod-html">Код HTML</a></li> <li class="sub sub_1"><a href="#kod-javascript">Код Javascript</a></li> <li class="top"><a href="#v-zaklyuchenie">В заключение</a></li> </ul> </div>
Код Javascript
jQuery(document).ready(function ($) {
    // Определяем мобильный браузер
    function MobileDetect() {
        var UA = navigator.userAgent.toLowerCase();
        return (/android|webos|iris|bolt|mobile|iphone|ipad|ipod|iemobile|blackberry|windows phone|opera mobi|opera mini/i.test(UA)) ? true : false;
    }
// Если не мобильная версия сайта и содержание статьи существует
if (!MobileDetect() && $('.kc__wrap').length) {
    // В сайдбар добавляем обёртку для дубля содержания статьи
    $('.sidebar').append('<section class="widget" id="post-content-list"><div class="widget-wrap" id="widget-wrap-content-list"></div></section>');
    // Клонируем содержание статьи и добавляем её внутрь обёртки
    $('.kc__wrap').clone().appendTo('#widget-wrap-content-list');
    // Счищаем ненужную обёртку
    $(".contents", '#widget-wrap-content-list').unwrap();
    // Добавляем ссылку для прокрутки вверх
    $('.content-list-title', '#widget-wrap-content-list').append('<div style="float:right" data-pr="↑ Наверх ↑" class="link gototop"></div>');
    // При клике по gototop прокручиваем вверх
    $('.gototop', '.content-list-title').on('click', function () {
        $("html, body").animate({
            'scrollTop': 0
        }, 600);
    });
    var // Объявляем переменные
    $l = $('#post-content-list'), // Контейнер виджета дубля содержания страницы
        $ot = $l.offset().top, // Координаты верха виджета, $PostContentListOffsetTop
        $lh = $l.outerHeight(true), // Высота виджета меню, $PostContentListHeight
        $p = $('.post'), // Контейнер поста
        $w = $(window); // Контейнер главного окна 
    // Если содержание не помещается в окно, удаляем его 
    if ( $lh > $w.height() ) $l.remove();
    // Обрабатываем событие скролла 
    $w.on('scroll', function () { //console.log($('.post').height(), " ",  eval($('#post-content-list').offset().top + $lh));
        // Высота статьи
        var $ph = $p.height();
        // Координаты скролла по вертикали
        var $wst = $w.scrollTop();
        // Если прошли ниже, чем макушка виджета меню...
        if ($wst > $ot &&
        // ...и если не достигли конца статьи
        $ph > $wst + $lh) {
            $l.css({
                "position": "fixed",
                    "top": 0,
                    "width": "360px"
            }).fadeIn();
        }
        // Когда дошли до конца статьи, скрываем содержание статьи 
        else if ($ph < $wst + $lh) {
            $l.fadeOut();
        }
        // Иначе убираем фиксацию
        else {
            $l.css({
                "position": "relative",
                    "top": 0,
                    "width": "360px"
            }).fadeIn();
        }
    });
}
});
В заключение
Если вам понравилась статья, но что-то не получается переделать под свои нужды, не стесняйтесь спрашивать об этом в комментариях, вместе найдём решение.

 (8 оценок, в среднем: 4,63 из 5)
Свежие комментарии