web-dev-qa-db-fra.com

Arrêtez la position fixe au pied de page

Je cherche une solution au problème populaire consistant à arrêter un objet fixe au bas de la page.

J'ai essentiellement une boîte de partage partagée dans le coin inférieur gauche de l'écran et je ne veux pas qu'elle défile au-dessus du pied de page. Je dois donc m'arrêter à environ 10px au-dessus du pied de page.

J'ai examiné d'autres questions ici ainsi que d'autres. La démo la plus simple et la plus simple que j'ai pu trouver est http://jsfiddle.net/bryanjamesross/VtPcm/ mais je ne pouvais pas la faire fonctionner avec ma situation.

Voici le code HTML pour la boîte de partage:

    <div id="social-float">
        <div class="sf-Twitter">
            ...
        </div>

        <div class="sf-facebook">
            ...
        </div>

        <div class="sf-plusone">
            ...
        </div>
    </div>

... et le CSS:

#social-float{
position: fixed;
bottom: 10px;
left: 10px;
width: 55px;
padding: 10px 5px;
text-align: center;
background-color: #fff;
border: 5px solid #ccd0d5;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
display: none;
}

Le pied de page est #footer et il n’a pas de hauteur fixe, si cela fait une différence.

Si quelqu'un pouvait m'aider à créer une solution jQuery simple pour cela, je l'apprécierais beaucoup!

33
scferg5

Démo en direct

tout d'abord, vérifiez son décalage chaque fois que vous faites défiler la page

$(document).scroll(function() {
    checkOffset();
});

et rendre sa position absolue s'il a été abaissé sous 10px avant le pied de page.

function checkOffset() {
    if($('#social-float').offset().top + $('#social-float').height() 
                                           >= $('#footer').offset().top - 10)
        $('#social-float').css('position', 'absolute');
    if($(document).scrollTop() + window.innerHeight < $('#footer').offset().top)
        $('#social-float').css('position', 'fixed'); // restore when you scroll up
}

remarquez que le parent de #social-float doit être frère du pied de page

<div class="social-float-parent">
    <div id="social-float">
        something...
    </div>
</div>
<div id="footer">
</div>

bonne chance :)

52
Sang

Je viens de résoudre ce problème sur un site sur lequel je travaille et je pensais le partager dans l'espoir que cela aide quelqu'un.

Ma solution prend la distance entre le pied de page et le haut de la page. Si l'utilisateur a fait défiler l'écran plus loin, il soulève la barre latérale avec une marge négative.

$(window).scroll(() => { 
  // Distance from top of document to top of footer.
  topOfFooter = $('#footer').position().top;
  // Distance user has scrolled from top, adjusted to take in height of sidebar (570 pixels inc. padding).
  scrollDistanceFromTopOfDoc = $(document).scrollTop() + 570;
  // Difference between the two.
  scrollDistanceFromTopOfFooter = scrollDistanceFromTopOfDoc - topOfFooter;

  // If user has scrolled further than footer,
  // pull sidebar up using a negative margin.
  if (scrollDistanceFromTopOfDoc > topOfFooter) {
    $('#cart').css('margin-top',  0 - scrollDistanceFromTopOfFooter);
  } else  {
    $('#cart').css('margin-top', 0);
  }
});
20
user1097431

J'ai récemment rencontré le même problème et publié ici ma solution également: Empêcher qu'un élément n'apparaisse au-dessus du pied de page lors de l'utilisation de position: fixed

Vous pouvez réaliser une solution en exploitant la propriété position de l'élément avec jQuery, en basculant entre la valeur par défaut (static pour divs), fixed et absolute. Vous aurez également besoin d'un élément conteneur pour votre élément fixe. Enfin, pour éviter que l'élément fixe ne dépasse le pied de page, cet élément conteneur ne peut pas être le parent du pied de page.

La partie javascript implique le calcul de la distance en pixels entre votre élément fixe et le haut du document et sa comparaison avec la position verticale actuelle de la barre de défilement par rapport à l’objet window (c’est-à-dire le nombre de pixels au-dessus qui sont cachés de la zone visible. de la page) à chaque fois que l'utilisateur fait défiler la page . Lorsque, lorsque vous faites défiler l'écran, l'élément fixe est sur le point de disparaître, vous changez sa position et fixez-le en haut de la page. 

Cela fait que l’élément fixe passe au bas de la page lorsque nous faisons défiler la page vers le bas, en particulier si la fenêtre du navigateur est petite . Nous allons donc calculer la distance en pixels du pied de page à partir du haut du document et la comparer avec la hauteur de l'élément fixe plus la position verticale de la barre de défilement: lorsque l'élément fixe est sur le point de franchir le pied de page, nous modifions sa position en absolu et nous nous en tenons au bas, juste au-dessus du pied de page.

Voici un exemple générique.

La structure HTML:

<div id="content">
    <div id="leftcolumn">
        <div class="fixed-element">
            This is fixed 
        </div>
    </div>
    <div id="rightcolumn">Main content here</div>
    <div id="footer"> The footer </div>
</div>  

Le CSS:

#leftcolumn {
    position: relative;
}
.fixed-element {
    width: 180px;
}
.fixed-element.fixed {
    position: fixed;
    top: 20px;
}
.fixed-element.bottom {
    position: absolute;
    bottom: 356px; /* Height of the footer element, plus some extra pixels if needed */
}

Le JS:

// Position of fixed element from top of the document
var fixedElementOffset = $('.fixed-element').offset().top;
// Position of footer element from top of the document.
// You can add extra distance from the bottom if needed,
// must match with the bottom property in CSS
var footerOffset = $('#footer').offset().top - 36;

var fixedElementHeight = $('.fixed-element').height(); 

// Check every time the user scrolls
$(window).scroll(function (event) {

    // Y position of the vertical scrollbar
    var y = $(this).scrollTop();

    if ( y >= fixedElementOffset && ( y + fixedElementHeight ) < footerOffset ) {
        $('.fixed-element').addClass('fixed');
        $('.fixed-element').removeClass('bottom');          
    }
    else if ( y >= fixedElementOffset && ( y + fixedElementHeight ) >= footerOffset ) {
        $('.fixed-element').removeClass('fixed');           
        $('.fixed-element').addClass('bottom');
    }
    else {
        $('.fixed-element').removeClass('fixed bottom');
    }

 });
4
Emanuele Pane

Voici la solution @Sang mais sans Jquery.

var socialFloat = document.querySelector('#social-float');
var footer = document.querySelector('#footer');

function checkOffset() {
  function getRectTop(el){
    var rect = el.getBoundingClientRect();
    return rect.top;
  }
  
  if((getRectTop(socialFloat) + document.body.scrollTop) + socialFloat.offsetHeight >= (getRectTop(footer) + document.body.scrollTop) - 10)
    socialFloat.style.position = 'absolute';
  if(document.body.scrollTop + window.innerHeight < (getRectTop(footer) + document.body.scrollTop))
    socialFloat.style.position = 'fixed'; // restore when you scroll up
  
  socialFloat.innerHTML = document.body.scrollTop + window.innerHeight;
}

document.addEventListener("scroll", function(){
  checkOffset();
});
div.social-float-parent { width: 100%; height: 1000px; background: #f8f8f8; position: relative; }
div#social-float { width: 200px; position: fixed; bottom: 10px; background: #777; }
div#footer { width: 100%; height: 200px; background: #eee; }
<div class="social-float-parent">
    <div id="social-float">
        float...
    </div>
</div>
<div id="footer">
</div>

3
Lionel Paulus

Cela a fonctionné pour moi -

HTML -

<div id="sideNote" class="col-sm-3" style="float:right;">

</div> 
<div class="footer-wrap">
        <div id="footer-div">
        </div>      
</div>

CSS - 

#sideNote{right:0; margin-top:10px; position:fixed; bottom:0; margin-bottom:5px;}

#footer-div{margin:0 auto; text-align:center; min-height:300px; margin-top:100px; padding:100px 50px;}

JQuery - 

function isVisible(elment) {
    var vpH = $(window).height(), // Viewport Height
        st = $(window).scrollTop(), // Scroll Top
        y = $(elment).offset().top;

    return y <= (vpH + st);
}

function setSideNotePos(){
    $(window).scroll(function() {
        if (isVisible($('.footer-wrap'))) {
            $('#sideNote').css('position','absolute');
            $('#sideNote').css('top',$('.footer-wrap').offset().top - $('#sideNote').outerHeight() - 100);
        } else {
            $('#sideNote').css('position','fixed');
            $('#sideNote').css('top','auto');
        }
    });
}

Maintenant, appelez cette fonction comme ceci -

$(document).ready(function() {
    setSideNotePos();
});

PS - Les fonctions Jquery sont copiées d’une réponse à une autre question similaire sur stackoverflow, mais cela ne fonctionnait pas complètement pour moi. Donc je l'ai modifié pour ces fonctions, comme elles sont montrées ici. Je pense que les attributs de position etc. de vos divs dépendront de la structure de ceux-ci, de l'identité de leurs parents et de leurs frères et soeurs.

La fonction ci-dessus fonctionne lorsque sideNote et footer-wrap sont des frères et sœurs directs.

2
Nalin Agrawal

Vous pouvez maintenant utiliser 

#myObject{
  position:sticky;
}

J'espère que cela t'aides..

1
Arthur M

Je suis allé avec une modification de la réponse de @ user1097431:

function menuPosition(){
// distance from top of footer to top of document
var footertotop = ($('.footer').position().top);
// distance user has scrolled from top, adjusted to take in height of bar (42 pixels inc. padding)
var scrolltop = $(document).scrollTop() + window.innerHeight;
// difference between the two
var difference = scrolltop-footertotop;

// if user has scrolled further than footer,
// pull sidebar up using a negative margin
if (scrolltop > footertotop) {
    $('#categories-wrapper').css({
       'bottom' : difference
   });
}else{
    $('#categories-wrapper').css({
       'bottom' : 0
   });
 };
};
0
Brainmaniac
$(window).scroll(() => {
    const footerToTop = $('.your-footer').position().top;
    const scrollTop = $(document).scrollTop() + $(window).height();
    const difference = scrollTop - footerToTop;
    const bottomValue = scrollTop > footerToTop ? difference : 0;
    $('.your-fixed-element').css('bottom', bottomValue);
});
0
Ali Klein