Как сделать эффект залипания при прокручивании страницы на блоках навигации, меню и любых других без дёрганий и анимации. Используем обычный 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(); } }); } });
В заключение
Если вам понравилась статья, но что-то не получается переделать под свои нужды, не стесняйтесь спрашивать об этом в комментариях, вместе найдём решение.
Свежие комментарии