web-dev-qa-db-fra.com

Twitter Bootstrap Affix - comment coller au fond?

J'ai lu la documentation et j'ai l'impression de faire exactement ce qu'ils montrent dans leurs exemples. Pourtant, lorsque je l'essaie, je ne peux pas que cela fonctionne. Je voudrais que cela fonctionne d'une manière similaire à la documentation. Il devient position:fixed après avoir fait défiler l'en-tête, puis lorsqu'il touche le pied de page, il devient position:absolute et reste en bas.


DEMO: http://jsfiddle.net/uvnGP/1/

JS

$("#account-overview-container").affix({
    offset: {
        top: $("header").outerHeight(true),
        bottom: $("footer").outerHeight(true)
    }
});

TOUPET

#account-overview-container {
    &.affix{
        top:10px;
        bottom:auto;
    }

    &.affix-top{
        //Do I need this?
    }

    &.affix-bottom{
        position:absolute;
        top:auto;
        bottom:140px;
    }
}
20
Chris Barr

Il y a quelques changements de votre code mais la solution convient pour la hauteur variable de l'en-tête et du pied de page, la largeur de réponse et peut être modifiée pour l'en-tête fixe.

Voici le lien

http://jsfiddle.net/uvnGP/131/

Le problème était que, lorsque l'affixe a touché le bas, il y avait un style css top et bottom ajouté à votre conteneur (#sidebar), la façon de le corriger consiste à réinitialiser ce bottom style à auto, ainsi seul le style top sera actif sur votre conteneur

voici le code:

var headerHeight = $('header').outerHeight(true); // true value, adds margins to the total height
var footerHeight = $('footer').innerHeight();
$('#account-overview-container').affix({
    offset: {
        top: headerHeight,
        bottom: footerHeight
    }
}).on('affix.bs.affix', function () { // before affix
    $(this).css({
        /*'top': headerHeight,*/    // for fixed height
            'width': $(this).outerWidth()  // variable widths
    });
}).on('affix-bottom.bs.affix', function () { // before affix-bottom
    $(this).css('bottom', 'auto'); // THIS is what makes the jumping
});
13
Paco Rivera

Si cela ne vous dérange pas d'utiliser des attributs 'data-' dans le balisage au lieu de SASS, cela devrait fonctionner:

http://www.bootply.com/l95thIfavC

Vous verrez également que j'ai supprimé l'affixe JS.

HTML

<div class="well well-small affix-top" data-spy="affix" data-offset-top="150" id="account-overview-container">

CSS

body{
    position:relative;
}
header,
footer{
    background: #ccc;
    padding:40px 0;
    text-align:center;
}
header{
    margin-bottom: 10px;
}

.affix-top {
    top: 155px;
    position:absolute;
}
.affix {
    bottom:140px;
}

Mise à jour pour Bootstrap 3

Pour utiliser affix-bottom, vous devez en principe définir la hauteur du pied de page ou de l’espace sous l’élément apposé. Voici un exemple: http://www.bootply.com/l95thIfavC

2
Zim

Réponse courte: Veillez à ce que le contenu de votre affixe n'utilise pas box-sizing: border-box; si vous utilisez des bordures.

Explication: La fonction jQuery offset() utilisée dans affix.js pour calculer la position actuelle de l'élément par rapport au document ne prend pas en compte les bordures.

Remarque: jQuery ne prend pas en charge l'obtention des coordonnées de décalage des éléments masqués ni la comptabilisation des bordures, des marges ou des marges de remplissage définies sur l'élément body.

Ainsi, si le contenu à l'intérieur de votre affixe a une bordure et que box-sizing est défini sur border-box, la hauteur inclura la bordure mais pas le décalage, ce qui entraînera un léger décalage de l'affix de calcul.

1
daddeo

La solution de Paco Rivera fonctionne! Mais pas comme il le souhaitait…. Wat supprime vraiment le problème du scintillement (saut):

.on('affix.bs.affix', function () { // before affix
    $(this).css({
        'width': $(this).outerWidth()  // variable widths
    });
})

Weired assez, vous n'avez même pas à définir la largeur CSS. La simple lecture de ce paramètre aide déjà. J'ai simplifié le code au fragment suivant et cela fonctionne toujours:

.on('affix.bs.affix', function () { // before affix
    $(this).width();
});

Je vais le garder comme ça jusqu'à la prochaine version du plugin Bootstrap Affix, où j'espère qu'ils vont le réparer une fois pour toutes.

1
Konstantin

J'ai réussi à le faire fonctionner dans mon application, il s'agit de faire en sorte que le style du bas soit cohérent avec le fond transmis à l'appel d'affixe. Si votre pied de page a une hauteur fixe et que le parent le plus proche est le corps, il est alors important de transmettre la même valeur pour les deux. Cela fonctionne assez bien pour la documentation de Bootstrap 2.3 comme on le voit ici et ici .

-

Supposons maintenant que vous n'avez pas de pied de page à hauteur fixe:

Étape 1: parent placé le plus proche (parent décalé)

Tout d'abord, nous utilisons un positionnement absolu pour le coller au bas, mais comme votre parent le plus proche sera le corps (qui comprend votre pied de page), vous n'avez pas de valeur fixe pour le bas. Pour résoudre ce problème, nous devons créer un nouveau parent positionné qui englobe tout sauf le pied de page (important: l’entête sera probablement aussi à l’extérieur). Définissez position: relative; sur le .container en haut ou sur l'un de ses ancêtres (important: le pied de page doit figurer après cet élément).

Étape 2: hauteur du pied de page

Maintenant, votre fond est relatif à son conteneur au lieu de son corps, mais la valeur inférieure de l'affix (utilisée pour savoir quand coller l'affixe au fond) est toujours relative à l'extrémité du corps, vous devez donc lui transmettre une fonction qui calculent la hauteur des éléments après le conteneur, s'il ne s'agit que du pied de page, cela suffit: $('footer').outerHeight(true).

Étape 3: Dépannage

Maintenant, tout est correct, mais trois choses peuvent toujours causer une mauvaise position du manche et un clignotement fou:

  1. Autres éléments visuels que le pied de page que vous n'avez pas pris en compte, tels que les pieds de page secondaires ou qui ne s'affichent pas toujours, tels que l'utile Rails-footnotes gem ;

  2. Les extensions de navigateur qui ajoutent des éléments au DOM, si elles sont cachées ou non dans le flux, vous ne devez pas compter leur hauteur. Le moyen le plus simple de contourner ce problème consiste à ne compter que les éléments que votre application connaît, mais une extension pourrait se terminer. briser votre application. Vous pouvez tester si une extension vous cause des problèmes en utilisant un navigateur ou une configuration sur laquelle vous n'avez pas d'extension installée, ou tout simplement en allant en "mode porno" (Incognito on Chromium (Ctrl+Shift+n), Navigation privée sur Firefox (Ctrl+Shift+p)) si vous n'avez pas activé les extensions dessus.

  3. Les bibliothèques Javascript ajoutent également des éléments au DOM, vous ne devez pas compter leur hauteur également.

Pour résoudre ces problèmes, vous pouvez essayer de le faire fonctionner avec le mot entier (CoffeeScript avec Underscore.js):

_($('footer').nextAll(':visible').addBack())
  .filter((el) -> el.offsetParent?)
  .reduce(((memo, el) -> memo + $(el).outerHeight(true)), 0)

Même chose, avec Javascript et jQuery.fn.each:

var sum = 0
$('footer').nextAll(':visible').each(function() {
  this.offsetParent != null && sum += $(this).outerHeight(true)
}
return sum

Ou vous pouvez ne rendre compte que des éléments que vous connaissez (je préfère celui-ci, l'autre que j'ai codé pour le défi):

$('footer').outerHeight(true) + ($('#footnotes_debug').outerHeight(true) || 0)
1
michelpm

Il suffit de remplacer le segment de code pour affixer dans bootstrap comme indiqué ci-dessous.

Ça va - 

this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() }) 

et cela le remplace 

this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })

À votre santé.

0
Rohan

Votre violon semble fonctionner comme vous le souhaitez si vous augmentez un peu la taille de la fenêtre. Considérant que le site Web serait inutilisable aux dimensions où l'affixe se rompt, vous devez soit l'ignorer, soit modifier la mise en page pour utiliser le plus petit espace au lieu d'essayer de résoudre le problème. L'affixe bootstrap dans la documentation n'est pas utilisé pour les résolutions plus petites, et je ferais de même.

0

Une solution possible consiste à ignorer complètement la situation affix-bottom en définissant bottom: null comme suit:

$("#my-selector").affix({
    offset: {
        top: $("#some-thing").outerHeight(true),
        bottom: null
    }
});
0
Chris Barr

Définissez la position du menu en bas à l'aide des propriétés position et top, bottom et utilisez la démo ici http://www.tutorialspark.com/twitterBootstrap/TwitterBootstrap_Affix.php

0
user2719087

J'ai fait ce travail via un processus d'essai et d'erreur mais c'est ce qui a fonctionné pour moi.

JS

$(document).ready(function() {
var SidebarTop = $('#your-affix').offset().top - x; //adjust x to meet your required positioning
    SidebarBottom = $('.site-footer').outerHeight() + x;

    $('#your-affix').affix({
        offset: {
        top: SidebarTop,
        bottom: SidebarBottom
        }
    });
});

CSS

#your-affix.affix {
    top: boo px; //the px from top of the window where you want your sidebar
                 //be when you scroll
    width: foo px; //your sidebar width
  }
#your-affix.affix-bottom {
    position: absolute;
    width: foo px; //your sidebar width
}

Après ce code, la barre latérale devient "non épinglée" lorsqu'elle atteint le pied de page. Et arrête de sauter en haut du site lorsqu'il atteint l'option offset inférieure.

0
Oksana Romaniv

Définissez position: absolute pour .affix-top & .affix-bottom et position: fixed pour .affix.

Selon officiel doc

0
Stream Huang