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.

3 Answers 3

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
    Commented Feb 4, 2019 at 20:46
  • Doesn't work for me. Missing steps?
    – John
    Commented Feb 6, 2019 at 10:13
  • which Magento version you are using?
    – Sanju
    Commented Feb 18, 2019 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 and acknowledge you have read our privacy policy.

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