Topic on Project:Support desk

Offset anchor targets to account for sticky navbar

2
Summary by JeremiPlazas

For anyone wondering. I figured out the problem. The parent element of span.mw-headline had overflow: hidden;set, which prevented any CSS solution from working. See thread for details.

JeremiPlazas (talkcontribs)

Hi there,

I'm using Mediawiki with a custom skin on this new website we launched. I have tried everything under the sun to offset the achor links' destinations to account for the navbar height and actually show up. I can not get it to work on mobile. I have a toggle menu in mobile view with the TOC in there. When a TOC link is clicked, it closes the menu and goes to the proper header. But no offsetting technique seems to work. Some JS snippets i've found will overwrite the default option but the offset is all over the place and you end up on a completely random part of the page. To clarify, some JS techniques do work on Desktop, that is not my concern, i can get it to work on desktop. Mobile though...

See for yourselves: https://buddhanature.tsadra.org/index.php/Articles/A_History_of_Buddha-Nature_Theory:_The_Literature_and_Traditions

Try the links in the "Content" section in the sidebar.


Here's what i've tried:

CSS
.mw-headline {
     margin-top: -100px;
     padding-top: 100px;
     display: block;
}
.mw-headline::before {
     display: block;
     content: " ";
     margin-top: -285px;
     height: 285px;
     visibility: hidden;
     pointer-events: none;
}
.toc a:target::before {
     content: "";
     display: block;
     height: 100px; /* fixed header height*/
     margin: -100px 0 0; /* negative fixed header height */
}
JS
jQuery(function($) {
  $('a[href*="#"]:not([href="#"])').click(function(e) {
     if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') || location.hostname == this.hostname) {
      var target = $(this.hash);
      headerHeight = 100;
      target = target.length ? target : $('[id="' + this.hash.slice(1) +'"]');
      if (target.length) {
        $('html,body').stop().animate({
          scrollTop: target.offset().top - headerHeight //offsets for fixed header
        }, 'linear');
      }
    }
  });
}); 
$("a[href^='#']").not(".no-offset a").click(function(e) {
	if ($(e.target.hash)) {
		var hash = e.currentTarget.hash.substring(1);
		var anchorTagOffset = $("*[id='" + hash + "']").offset().top - 100;
		$('body').animate({
			scrollTop : anchorTagOffset,
		}, 100);
	}
});
jQuery(function($) { 
	$('a[href^="#"]').click(function(event){
	    event.preventDefault();
	    var target_offset = $(this.hash.substring(1)).offset() ? $(this.hash.substring(1)).offset().top : 0;
	    //change this number to create the additional off set        
	    var customoffset = 100;
	    $('html, body').animate({scrollTop:target_offset - customoffset}, 200);
	});
};


Any clues or suggestions as to what direction i should go into?

I've also tried to switch the behavior of the navbar from sticky to fixed (I'm using Bootstrap 4) and add a top padding/margin to the body element. No luck either.

I'm asking here in case anyone has information about this as it relates to the wiki software itself.

Thanks in advance!

JeremiPlazas (talkcontribs)

For anyone wondering. I figured out the problem. The parent element of span.mw-headline had overflow: hidden;set, which prevented any CSS solution from working. Here's what i did in the end:

JS
$('span.mw-headline').each(function() {
	$(this).addClass('offset-header');
	$(this).parent().css('overflow', 'visible');
});
CSS
.offset-header {
    display: block;
    margin-top: -100px;
    padding-top: 100px;
}

This did the trick for me.

Cheers.