0

I'm following the answer in this topic to keep header sticky. So far I've created vendor/theme/web/js/sticky.js with the following content:

require([ "jquery" ], function($) {
    $(window).scroll(function() {
        if ($(window).scrollTop() > $('#header').offset().top && !($('#header').hasClass('sticky'))) {
            $('#header-2').addClass('sticky');
        } else if ($(window).scrollTop() == 0) {
            $('#header').removeClass('sticky');
        }
    });
});

and called this file inside vendor/theme/Magento_Theme/layout/default_head_blocks.xml

<link src="js/sticky.js"/>

Second part of this answer says:

"add some css to this sticky class like this:"

#header.sticky {
    background: #fff none repeat scroll 0 0;
    border-bottom: 4px solid #325052;
    margin: 0 auto;
    max-width: 100%;
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 99;
}

How can I implement this part? I've tried creating a css/sticky.css file with the code above and link it on default_head_blocks.xml ( <css src="css/sticky.css"/> ), but it's not working.

5

You can use default M2 Sticky

define([
    'jquery', 
    'mage/mage', 
    'domReady!'
], function ($) {
    $('#header').mage('sticky', {
        container: '#maincontent',
        spacingTop: 0
    });
});

And CSS

#header {
  position: relative;
}
3
  • This is the better answer – Leland Feb 4 '19 at 20:46
  • Doesn't work for me. Missing steps? – John Feb 6 '19 at 10:13
  • which Magento version you are using? – Sanju Feb 18 '19 at 11:55
2

So I forgot to replace some #header placeholders, correct code below.

Update: I've added padding ( to prevent pixel skipping ) and mobile support ( to pad correct element on mobile interface )

vendor/theme/web/js/sticky.js :

require([ "jquery" ], function($) {
    if( $(window).width() >= 768 ) {
        $(window).scroll(function() {
            if ($(window).scrollTop() > $('.page-header').offset().top && !($('.page-header').hasClass('sticky')) && !($('.sections.nav-sections').hasClass('padding'))) {
                $('.page-header').addClass('sticky');
                $('.sections.nav-sections').addClass('padding');
            } else if ($(window).scrollTop() == 0) {
                $('.page-header').removeClass('sticky');
                $('.sections.nav-sections').removeClass('padding');
            }
        });
    }
    else
    {
        $(window).scroll(function() {
            if ($(window).scrollTop() > $('.page-header').offset().top && !($('.page-header').hasClass('sticky')) && !($('.page-main').hasClass('paddingm'))) {
                $('.page-header').addClass('sticky');
                $('.page-main').addClass('paddingm');
            } else if ($(window).scrollTop() == 0) {
                $('.page-header').removeClass('sticky');
                $('.page-main').removeClass('paddingm');
            }
        });
    }   
});

vendor/theme/web/css/sticky.css :

.sticky {
    background: #fff none repeat scroll 0 0;
    border-bottom: 2px solid #131313;
    margin: 0 auto;
    max-width: 100%;
    max-height: 109px;
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 99;
}

.padding {
    padding-top: 126px;
}

.paddingm {
    padding-top: 107px;
}

( max-height and padding-top values depend on header's height )

0

For Sticky Product page Image Some time issue with sticky properties so We can used jquery in direct phtml file for magento 2.

<script>

require([ "jquery" ], function($){
    $(document).ready(function(){
            let mediaTop = $('.product.media').offset().top;
            let mediaHeight = $('.product.media').height() - 52;
            let mediaBottom = mediaTop + mediaHeight;
            $(window).scroll(() => {
                var width = $(window).width();
                if(width > 1024) {
                        if($(window).scrollTop() >= 200){
                            let infoBottom = $('.product-info-main').offset().top + $('.product-info-main').height();
                            if(mediaBottom <= infoBottom) {
                                let scrollTop = $(window).scrollTop();
                                let mediaTopAdjust = Math.max((scrollTop - mediaTop), 0);
                                let newMediaBottom = mediaTop + mediaTopAdjust + mediaHeight;
                                let bottomHeightDiff = infoBottom - mediaBottom;
                                if(newMediaBottom <= infoBottom) {
                                    $('.product.media').css('top','0');
                                    $('.product.media').css('position', 'fixed');
                                } else {
                                        $('.product.media').css('top', bottomHeightDiff + 'px');
                                        $('.product.media').css('position', 'relative');
                                    }
                            }
                        } else {
                                $('.product.media').css('position', 'relative');
                                $('.product.media').css('margin-top', "");
                            }
                }
            });
    });
});

</script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.