XF 2.1 What does XenForo use to create an offset for #target links to compensate for the fixed header?

bzcomputers

Well-known member
I am working on some custom pages with #target links within the page, currently in the form of a table of contents at the top of the page. The issue is, the targeted positions are all off by -45px due to the fixed header at the top of the page.

I see somehow this is not an issue for #target links within the XenForo forum (for instance post links). It appears this offset is already compensated for through existing script.

Where is this script and what do I need to do to have it active on a custom page?

My alternative is to run some additional jQuery smooth scrolling code like below:
JavaScript:
$('.scroll').on('click',function(e) {
    e.preventDefault();
    var offset = 0;
    var target = this.hash;
    if ($(this).data('offset') != undefined) offset = $(this).data('offset');
    $('html, body').stop().animate({
        'scrollTop': $(target).offset().top - offset
    }, 500, 'swing', function() {
        // window.location.hash = target;
    });
});

Then I can add a data-offset field to the scroll link:
HTML:
<a class="scroll" href="#target" data-offset="45">Scroll to Target</a>

...but if it is already done within XenForo I might as well use the existing code.
 
Thanks for pointing me in the right direction...

It looks like XenForo uses:

HTML:
<span class="u-anchorTarget" id="target-id-here"></span>

CSS:
.u-anchorTarget
{
    display: block;
    height: 0;
    width: 0;
    visibility: hidden;
    pointer-events: none;
    position: absolute;
}

The <span> for #target IDs is hidden and absolutely positioned, so it is not affected by any fixed elements on the page like a header no matter what size it is.

My solution in the first post above would work, but would require code edits if the offset (size of the header / fixed element) ever changed in the future.
 
My solution in the first post above would work, but would require code edits if the offset (size of the header / fixed element) ever changed in the future.
To expand on this, and for future reference to anyone else who encounters it, this offset can easily be changed.

In app.less, simply add pixels to the height and margin-top properties. In this example below, I am moving the target offset "up" the page by an additional 30 pixels:

Less:
.u-anchorTarget
{
    .m-stickyHeaderConfig(@xf-publicNavSticky);
    height: (@_stickyHeader-height + @_stickyHeader-offset + 30);
    margin-top: -(@_stickyHeader-height + @_stickyHeader-offset + 30);
}

I needed to do this because I made moved the p-sectionlinks to be inside the sticky header container. The height of this additional element is obviously not included in the calculation in the default templates so I just had to make this quick change.
 
Yeah, also the anchor target for post links is a separate (hidden) span element. Take a look at the post_macros template for an idea (on or around line 9). :)

Thanks for pointing me in the right direction...

It looks like XenForo uses:

HTML:
<span class="u-anchorTarget" id="target-id-here"></span>

CSS:
.u-anchorTarget
{
    display: block;
    height: 0;
    width: 0;
    visibility: hidden;
    pointer-events: none;
    position: absolute;
}

The <span> for #target IDs is hidden and absolutely positioned, so it is not affected by any fixed elements on the page like a header no matter what size it is.

My solution in the first post above would work, but would require code edits if the offset (size of the header / fixed element) ever changed in the future.

To expand on this, and for future reference to anyone else who encounters it, this offset can easily be changed.

In app.less, simply add pixels to the height and margin-top properties. In this example below, I am moving the target offset "up" the page by an additional 30 pixels:

Less:
.u-anchorTarget
{
    .m-stickyHeaderConfig(@xf-publicNavSticky);
    height: (@_stickyHeader-height + @_stickyHeader-offset + 30);
    margin-top: -(@_stickyHeader-height + @_stickyHeader-offset + 30);
}

I needed to do this because I made moved the p-sectionlinks to be inside the sticky header container. The height of this additional element is obviously not included in the calculation in the default templates so I just had to make this quick change.

Anyone know if this has changed in any way? The above solution seems to work for Safari on iOS but it's not working in Chrome on Android.
 
Top Bottom