Bootstrap Affix "Back to Top" Link

Bootstrap Affix Back to Top Link

Now that I understand the Affix component better, I have come up with the solution. After specifying a top offset and adjusting the CSS, it's working nicely. The link will scroll into view and then "pin" to the bottom. For pages which do not have a scroll bar, the link is never enabled. I've updated the JS Fiddle (here) with a working example. Key pieces are:

HTML:

<!-- child of the body tag -->
<span id="top-link-block" class="hidden">
<a href="#top" class="well well-sm" onclick="$('html,body').animate({scrollTop:0},'slow');return false;">
<i class="glyphicon glyphicon-chevron-up"></i> Back to Top
</a>
</span><!-- /top-link-block -->

JS:

<script>
// Only enable if the document has a long scroll bar
// Note the window height + offset
if ( ($(window).height() + 100) < $(document).height() ) {
$('#top-link-block').removeClass('hidden').affix({
// how far to scroll down before link "slides" into view
offset: {top:100}
});
}
</script>

CSS:

<style>
#top-link-block.affix-top {
position: absolute; /* allows it to "slide" up into view */
bottom: -82px;
left: 10px;
}
#top-link-block.affix {
position: fixed; /* keeps it on the bottom once in view */
bottom: 18px;
left: 10px;
}
</style>

Note: I was not able to use the affix bottom offset (example) to hide the link for short pages due to a bug with affix container height calculation (Bootstrap Issue # 4647). I'm sure there is a workaround and would welcome the solution to this method.

Bootstrap affix does not work when navigating back

I think that the problem I was experiencing was due to a mismatch between the top and bottom offset values, leading to the affix plugin not knowing what state it should be in. It may be a bug in the affix plugin or how it is applied (read more at https://github.com/twbs/bootstrap/issues/4647). It also seems to manifest differently in different browsers.

In my case I could only solve it by removing the bottom offset:

$('#engage').affix({
offset: {
top: $('#donation-content').offset().top
}
});

This does mean that the fixed div can overlap the footer in some situations, which is not ideal but it is more stable. I am marking this as the accepted answer for now, because it does solve the problem, though it does leave unfortunate side-effects.

bootstrap menu top affix

You need to apply the z-index to the #nav not the .nav-wrapper:

#nav { 
position: relative;
z-index: 2;
}

Demo:
http://jsfiddle.net/t7pL3/

Switching bootstrap affix and affix-top class by scrolling make the elements below navbar move upward

And if you put the padding to the #content always? then you set absolute:position to .affix-top and relative to his parent for maintain in his place.

.nav-container-realestate {
position: relative;
}

.affix-top {
position: absolute;
width: 100%;
}

.affix {
top: 0;
width: 100%;
}

#content {
padding-top: 70px;
}

DEMO: https://jsfiddle.net/blonfu/9z683r2n/2/

Bootstrap affix navbar for single page with scrollspy and page anchors

I think your problem has only to do with the affix. I found a problem in 3 situations:

  1. no scroll and clicking a link
  2. click the first link
  3. scoll, click the first link and click an other link.

In this three situation you click from an position where you affix is not applied to a position where your affix has been applied.

What happens your click scrolls the target anchor to the top of the page and applies the affix (set navbar's position to fixed) after this. Result the navbar overlaps the content.

I don't think you could fix this with css only. I think your solution of adding a margin / padding to the section will be right, but you will have to apply the margin after the affix.

I tried something like:

var tmp = $.fn.affix.Constructor.prototype.checkPosition;
var i = 0;
var correct = false
$.fn.affix.Constructor.prototype.checkPosition = function () {
$('#content').css('margin-top','0');
tmp.call(this);

if(i%2!=0 && $(window).scrollTop()<443){correct=true}
if(i%2==0 && correct){$('#content').css('margin-top','83px').trigger('create'); correct=false}
i++;
}

This feels to complex and also only seems to work on firefox now.

update

I think i could fix your problem by overwritting the complete affix checkPosition function:

$.fn.affix.Constructor.prototype.checkPosition = function () 
{
if (!this.$element.is(':visible')) return

var scrollHeight = $(document).height()
var scrollTop = this.$window.scrollTop()
var position = this.$element.offset()
var offset = this.options.offset
var offsetTop = offset.top
var offsetBottom = offset.bottom
if(scrollTop==378)
{
this.$window.scrollTop('463');
scrollTop==463;
}
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top()
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()

var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
console.log(scrollTop + ':' + offsetTop);

if(scrollTop > offsetTop) {$('#content').css('margin-top','83px'); console.log('margin') }
else{$('#content').css('margin-top','0');}
if (this.affixed === affix) return

if (this.unpin) this.$element.css('top', '')

this.affixed = affix
this.unpin = affix == 'bottom' ? position.top - scrollTop : null

this.$element.removeClass('affix affix-top affix-bottom').addClass('affix' + (affix ? '-' + affix : ''))

if (affix == 'bottom') {
this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
}
}

Some values are hard coded (now) so this function only will work for your example on github pages.

Demo: http://bootply.com/81336

On github pages you use "old" versions of jQuery and Bootstrap. You don't need to set an offset for the scrollspy. You don't have to call $('#navbar').scrollspy(); also cause you already set the scrollspy with data attributes.

See also: https://github.com/twbs/bootstrap/issues/10670

remove this hardcode values

When clicking an internal link (start with #{id}) the anchor with id={id} will be scrolled to the top of the viewport.
In this case there will be a fixed navbar (affix) so the anchor should scroll to the top minus the height of the navbar.
The height of the navbar will be 85px (63 pixels of the brand image + 2 pixels of the border + the margin-bottom of 20 px of the .navbarheader)

This value will be used here:

if(scrollTop > offsetTop) {$('#content').css('margin-top','83px'); console.log('margin') }
else{$('#content').css('margin-top','0');}

I have used 83 (may look better?).
So the 83 can be replaced with: var navbarheight = $('#nav').innerHeight()

Then we have these:

if(scrollTop==378) 
{
this.$window.scrollTop('463');
scrollTop==463;//typo?? make no sense
}

The (first) link scrolls the anchor to the top where the affix is not
applied yet (below data-offset-top="443") the height of your fixed
navbar is not used in calculacting so this point will be 443 - 85
(navbarheight) = 378. This code could be replace with.

if(scrollTop==(443-navbarheight)) 
{
this.$window.scrollTop(scrollTop+navbarheight);
}

Note 443 now still will be hardcoded. It is also hardcoded in your
html with affix-top.

Watch out Replacing the values with the above won't work. The
situation between (af)fixed and not will change for every scroll
action. The part if(scrollTop==378) is a trick not a solution. It
solves the situation for scrollheight < data-offset-top. We could not
apply the whole range, case in that case the user can't never scroll
back to the top (this.$window.scrollTop scrolls him back again and again).

Also the calculation of navbarheight will be tricky. When the navbar
is fixed $('#nav').innerHeight() / height will return 85 (including
the margin). In the absolute position this will be 65.

Bootstrap Affix Nav Causes Div Below To Jump Up

This seems to work:

.nav-wrapper
{
min-height:50px;
}

Updated jsFiddle: http://jsfiddle.net/yYE62/5/

What's happening is that the affix plugin makes the element with the .affix class have a fixed position in the document. This removes the affixed element from the flow (or layout, if you prefer) and causes the container to collapse. When that happens, the content below slides up to fill the space that the affixed element used to occupy.

By adding the rule above, you tell that container to maintain a minimum height regardless of whether it has content or not. It doesn't have to be 50px; that's the default height of .navbar, so adjust to match your needs. If you don't want all .nav-wrappers to have a minimum height, assign an id and use that instead.

Bootstrap Affix fixed header after 100px making content jump

The flicker/jump is because the navbar is changing from position:static to postition:fixed. When the affix is applied at 100px, which is close the height of the navbar 92px, it's always going to "jump" unless you had a div of 100px in height above the navbar like in this question.

In your case, it looks like you're just trying to shrink the navbar padding after scrolling 100px, so in that case always keep the navbar postion:fixed and just adjust the padding when .affix is applied...

https://jsfiddle.net/etxyk0y1/1/

.navbar {
min-height: 50px;
z-index: 99998;
background:red;
width:100%;
position: fixed;
transition: all .5s;
top: 0;
}

.affix-top.navbar {
padding-bottom: 20px;
border: 1px solid transparent;
padding-top: 20px;
}

.affix.navbar {
padding-top: 10px;
padding-bottom: 10px;
font-size: 0.9em;
border-bottom: 1px solid #f9f7f3;
transition: all .5s;
}

Use the nav-wrapper to keep spacing between the fixed navbar and the content.

.nav-wrapper {
padding-top: 100px;
}


Related Topics



Leave a reply



Submit