Comment puis-je faire coller une div au haut de l'écran une fois qu'elle a été tournée?

je voudrais créer une div, qui est située sous un bloc de contenu, mais qui une fois que la page a été suffisamment déroulée pour entrer en contact avec sa limite supérieure, devient fixe en place et défile avec la page. Je sais que j'ai vu au moins un exemple de ceci en ligne mais je ne peux pas m'en souvenir pour la vie de moi.

une idée?

253
demandé sur Bill the Lizard 2009-08-01 11:54:31

21 réponses

vous pouvez utiliser simplement css, en positionnant votre élément comme fixe :

.fixedElement {
    background-color: #c0c0c0;
    position:fixed;
    top:0;
    width:100%;
    z-index:100;
}

Edit: Vous devriez avoir l'élément à la position absolue, une fois le rouleau offset a atteint l'élément, il doit être changé à fixe, et la position du haut doit être à zéro.

vous pouvez détecter l'offset de défilement du haut du document avec le scrollTop fonction:

$(window).scroll(function(e){ 
  var $el = $('.fixedElement'); 
  var isPositionFixed = ($el.css('position') == 'fixed');
  if ($(this).scrollTop() > 200 && !isPositionFixed){ 
    $el.css({'position': 'fixed', 'top': '0px'}); 
  }
  if ($(this).scrollTop() < 200 && isPositionFixed){
    $el.css({'position': 'static', 'top': '0px'}); 
  } 
});

lorsque le décalage de défilement atteint 200, l'élément stick sera placé en haut de la fenêtre du navigateur, parce qu'il est placé comme fixe.

217
répondu CMS 2018-09-13 14:48:43

vous avez vu cet exemple sur la page de publication de Google Code et (seulement récemment) sur la page d'édition de Stack Overflow.

la réponse DE CMS ne renverse pas le positionnement lorsque vous faites défiler vers le haut. Voici le code volé sans vergogne à Stack Overflow:

function moveScroller() {
    var $anchor = $("#scroller-anchor");
    var $scroller = $('#scroller');

    var move = function() {
        var st = $(window).scrollTop();
        var ot = $anchor.offset().top;
        if(st > ot) {
            $scroller.css({
                position: "fixed",
                top: "0px"
            });
        } else {
            $scroller.css({
                position: "relative",
                top: ""
            });
        }
    };
    $(window).scroll(move);
    move();
}
<div id="sidebar" style="width:270px;"> 
  <div id="scroller-anchor"></div> 
  <div id="scroller" style="margin-top:10px; width:270px"> 
    Scroller Scroller Scroller
  </div>
</div>

<script type="text/javascript"> 
  $(function() {
    moveScroller();
  });
</script> 

et un simple live demo .

une alternative naissante, sans écriture, est position: sticky , qui est pris en charge dans Chrome, Firefox, et Safari. Voir l'article sur HTML5Rocks et Démo , et Mozilla docs .

232
répondu Josh Lee 2017-07-19 11:57:50

j'ai eu le même problème que vous et j'ai fini par faire un plugin jQuery pour m'en occuper. Il résout en fait tous les problèmes que les gens ont énumérés ici, plus il ajoute un couple de fonctionnalités optionnelles trop.

Options

stickyPanelSettings = {
    // Use this to set the top margin of the detached panel.
    topPadding: 0,

    // This class is applied when the panel detaches.
    afterDetachCSSClass: "",

    // When set to true the space where the panel was is kept open.
    savePanelSpace: false,

    // Event fires when panel is detached
    // function(detachedPanel, panelSpacer){....}
    onDetached: null,

    // Event fires when panel is reattached
    // function(detachedPanel){....}
    onReAttached: null,

    // Set this using any valid jquery selector to 
    // set the parent of the sticky panel.
    // If set to null then the window object will be used.
    parentSelector: null
};

https://github.com/donnyv/sticky-panel

démo: http://htmlpreview.github.io/?https://github.com/donnyv/sticky-panel/blob/master/jquery.stickyPanel/Main.htm

33
répondu Donny V. 2015-03-12 19:10:15

depuis janvier 2017 et la sortie de Chrome 56, la plupart des navigateurs d'usage courant prennent en charge la propriété position: sticky dans CSS.

#thing_to_stick {
  position: sticky;
  top: 0px;
}

fait l'affaire pour moi dans Firefox et Chrome.

en Safari vous devez toujours utiliser position: -webkit-sticky .

Polyfills sont disponibles pour Internet Explorer et Edge; https://github.com/wilddeer/stickyfill semble être une bonne idée.

25
répondu Colin 't Hart 2017-01-26 10:32:45

Et voici comment sans jquery (mise à JOUR: voir les autres réponses où vous pouvez désormais le faire avec CSS)

var startProductBarPos=-1;
window.onscroll=function(){
  var bar = document.getElementById('nav');
  if(startProductBarPos<0)startProductBarPos=findPosY(bar);

  if(pageYOffset>startProductBarPos){
    bar.style.position='fixed';
    bar.style.top=0;
  }else{
    bar.style.position='relative';
  }

};

function findPosY(obj) {
  var curtop = 0;
  if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
    while (obj.offsetParent) {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
    curtop += obj.offsetTop;
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}
* {margin:0;padding:0;}
.nav {
  border: 1px red dashed;
  background: #00ffff;
  text-align:center;
  padding: 21px 0;

  margin: 0 auto;
  z-index:10; 
  width:100%;
  left:0;
  right:0;
}

.header {
  text-align:center;
  padding: 65px 0;
  border: 1px red dashed;
}

.content {
  padding: 500px 0;
  text-align:center;
  border: 1px red dashed;
}
.footer {
  padding: 100px 0;
  text-align:center;
  background: #777;
  border: 1px red dashed;
}
<header class="header">This is a Header</header>
<div id="nav" class="nav">Main Navigation</div>
<div class="content">Hello World!</div>
<footer class="footer">This is a Footer</footer>
19
répondu Jim W 2017-12-21 19:37:20

C'est comme ça que je l'ai fait avec jquery. Tout cela a été concocté à partir de diverses réponses sur le débordement de la pile. Cette solution cache les sélecteurs pour une performance plus rapide et résout également le problème de "saut" lorsque le Sticky div devient sticky.

Check it out on jsfiddle: http://jsfiddle.net/HQS8s /

CSS:

.stick {
    position: fixed;
    top: 0;
}

JS:

$(document).ready(function() {
    // Cache selectors for faster performance.
    var $window = $(window),
        $mainMenuBar = $('#mainMenuBar'),
        $mainMenuBarAnchor = $('#mainMenuBarAnchor');

    // Run this on scroll events.
    $window.scroll(function() {
        var window_top = $window.scrollTop();
        var div_top = $mainMenuBarAnchor.offset().top;
        if (window_top > div_top) {
            // Make the div sticky.
            $mainMenuBar.addClass('stick');
            $mainMenuBarAnchor.height($mainMenuBar.height());
        }
        else {
            // Unstick the div.
            $mainMenuBar.removeClass('stick');
            $mainMenuBarAnchor.height(0);
        }
    });
});
9
répondu JohnB 2013-03-26 00:44:20

Voici une autre option:

JAVASCRIPT

var initTopPosition= $('#myElementToStick').offset().top;   
$(window).scroll(function(){
    if($(window).scrollTop() > initTopPosition)
        $('#myElementToStick').css({'position':'fixed','top':'0px'});
    else
        $('#myElementToStick').css({'position':'absolute','top':initTopPosition+'px'});
});

votre #myElementToStick devrait commencer par position:absolute propriété CSS.

5
répondu kunde 2013-09-12 22:17:48

ma solution est un peu verbeuse, mais elle gère le positionnement variable à partir du bord gauche pour les mises en page centrées.

// Ensurs that a element (usually a div) stays on the screen
//   aElementToStick   = The jQuery selector for the element to keep visible
global.makeSticky = function (aElementToStick) {
    var $elementToStick = $(aElementToStick);
    var top = $elementToStick.offset().top;
    var origPosition = $elementToStick.css('position');

    function positionFloater(a$Win) {
        // Set the original position to allow the browser to adjust the horizontal position
        $elementToStick.css('position', origPosition);

        // Test how far down the page is scrolled
        var scrollTop = a$Win.scrollTop();
        // If the page is scrolled passed the top of the element make it stick to the top of the screen
        if (top < scrollTop) {
            // Get the horizontal position
            var left = $elementToStick.offset().left;
            // Set the positioning as fixed to hold it's position
            $elementToStick.css('position', 'fixed');
            // Reuse the horizontal positioning
            $elementToStick.css('left', left);
            // Hold the element at the top of the screen
            $elementToStick.css('top', 0);
        }
    }

    // Perform initial positioning
    positionFloater($(window));

    // Reposition when the window resizes
    $(window).resize(function (e) {
        positionFloater($(this));
    });

    // Reposition when the window scrolls
    $(window).scroll(function (e) {
        positionFloater($(this));
    });
};
1
répondu Josh Russo 2012-11-15 22:34:02

Voici une autre version à essayer pour ceux qui ont des problèmes avec les autres. Il rassemble les techniques discutées dans cette question dupliquée , et génère les DIVs helper nécessaires dynamiquement de sorte qu'aucun HTML supplémentaire n'est nécessaire.

CSS:

.sticky { position:fixed; top:0; }

JQuery:

function make_sticky(id) {
    var e = $(id);
    var w = $(window);
    $('<div/>').insertBefore(id);
    $('<div/>').hide().css('height',e.outerHeight()).insertAfter(id);
    var n = e.next();
    var p = e.prev();
    function sticky_relocate() {
      var window_top = w.scrollTop();
      var div_top = p.offset().top;
      if (window_top > div_top) {
        e.addClass('sticky');
        n.show();
      } else {
        e.removeClass('sticky');
        n.hide();
      }
    }
    w.scroll(sticky_relocate);
    sticky_relocate();
}

Pour en faire un élément collant, faire:

make_sticky('#sticky-elem-id');

lorsque l'élément devient collant, le code gère la position du contenu restant pour l'empêcher de sauter dans le vide laissé par l'élément collant. Il renvoie également l'élément sticky à sa position originale non-sticky lors du défilement vers l'arrière au-dessus de lui.

1
répondu Dan 2017-05-23 12:10:32

Voici une version étendue de la réponse de Josh Lee. Si vous voulez que le div soit sur la barre latérale à droite, et flotte dans une plage (i.e., vous devez spécifier les positions d'ancrage supérieur et inférieur). Il corrige également un bug lorsque vous le voyez sur les appareils mobiles (vous devez vérifier la position de défilement gauche sinon le div se déplacera de l'écran).

function moveScroller() {
    var move = function() {
        var st = $(window).scrollTop();
        var sl = $(window).scrollLeft();
        var ot = $("#scroller-anchor-top").offset().top;
        var ol = $("#scroller-anchor-top").offset().left;
        var bt = $("#scroller-anchor-bottom").offset().top;
        var s = $("#scroller");
        if(st > ot) {
            if (st < bt - 280) //280px is the approx. height for the sticky div
            {
                s.css({
                    position: "fixed",
                    top: "0px",
                    left: ol-sl
                }); 
            }
            else
            {
                s.css({
                    position: "fixed",
                    top: bt-st-280,
                    left: ol-sl
                }); 
            }
        } else {
            s.css({
                position: "relative",
                top: "",
                left: ""
            });

        }
    };
    $(window).scroll(move);
    move();
}
1
répondu realwecan 2013-12-23 03:03:21

je suis tombé sur ceci en cherchant la même chose. Je sais que c'est une vieille question, mais j'ai pensé vous donner une réponse plus récente.

Scrollorama a une fonction "pin it" qui est exactement ce que je cherchais.

http://johnpolacek.github.io/scrollorama /

1
répondu pbryd 2015-04-14 07:24:47

Comme Josh Lee et Colin 't Hart ai dit, vous pouvez éventuellement utiliser position: sticky; top: 0; l'application de la div que vous voulez le défilement...

de plus, la seule chose que vous aurez à faire est de le copier dans le haut de votre page ou de le formater pour s'adapter à une feuille CSS externe:

<style>
#sticky_div's_name_here { position: sticky; top: 0; }
</style>

il suffit de remplacer #sticky_div's_name_here par le nom de votre div, c.-à-d. si votre div était <div id="example"> vous #example { position: sticky; top: 0; } .

1
répondu Max Garner 2017-06-27 14:21:51

L'information fournie pour répondre à cette autre question peut vous être utile, Evan:

vérifier si l'élément est visible après défilement

vous voulez essentiellement modifier le style de l'élément pour le fixer à fixe seulement après avoir vérifié que le document.corps.la valeur scrollTop est égale ou supérieure au haut de votre élément.

0
répondu Amber 2017-05-23 12:18:17

la réponse acceptée fonctionne, mais ne revient pas à la position précédente si vous faites défiler au-dessus. Il est toujours collé au sommet après avoir été placé là.

  $(window).scroll(function(e) {
    $el = $('.fixedElement');
    if ($(this).scrollTop() > 42 && $el.css('position') != 'fixed') {
      $('.fixedElement').css( 'position': 'fixed', 'top': '0px');

    } else if ($(this).scrollTop() < 42 && $el.css('position') != 'relative') {
      $('.fixedElement').css( 'relative': 'fixed', 'top': '42px');
//this was just my previous position/formating
    }
  });

la réponse de jleedev fonctionnait, mais je n'ai pas réussi à la faire fonctionner. Sa page d'exemple ne marchait pas non plus (pour moi).

0
répondu Forge 2010-07-08 14:29:02

vous pouvez ajouter 3 lignes supplémentaires de sorte que lorsque l'utilisateur fait défiler vers le haut, le div va coller sur son ancienne place:

voici le code:

if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
    $('.fixedElement').css({'position': 'relative', 'top': '200px'});
}
0
répondu infinity 2010-10-02 11:31:26

j'ai des liens mis en place dans un div donc c'est une liste verticale de liens lettre et nombre.

#links {
    float:left;
    font-size:9pt;
    margin-left:0.5em;
    margin-right:1em;
    position:fixed;
    text-align:center;
    width:0.8em;
}

j'ai alors configuré cette fonction jQuery pratique pour enregistrer la position chargée et puis changer la position à fixe lors du défilement au-delà de cette position.

NOTE: cela ne fonctionne que si les liens sont visibles sur la page load!!

var listposition=false;
jQuery(function(){
     try{
        ///// stick the list links to top of page when scrolling
        listposition = jQuery('#links').css({'position': 'static', 'top': '0px'}).position();
        console.log(listposition);
        $(window).scroll(function(e){
            $top = $(this).scrollTop();
            $el = jQuery('#links');
            //if(typeof(console)!='undefined'){
            //    console.log(listposition.top,$top);
            //}
            if ($top > listposition.top && $el.css('position') != 'fixed'){
                $el.css({'position': 'fixed', 'top': '0px'});
            }
            else if ($top < listposition.top && $el.css('position') == 'fixed'){
                $el.css({'position': 'static'});
            }
        });

    } catch(e) {
        alert('Please vendor admin@mydomain.com (Myvendor JavaScript Issue)');
    }
});
0
répondu Artistan 2010-11-11 13:58:50

j'ai utilisé une partie du travail ci-dessus pour créer cette technologie. Je l'ai un peu améliorée et j'ai pensé que je partagerais mon travail. Espérons que cette aide.

Code jsfuddle

function scrollErrorMessageToTop() {
    var flash_error = jQuery('#flash_error');
    var flash_position = flash_error.position();

    function lockErrorMessageToTop() {
        var place_holder = jQuery("#place_holder");
        if (jQuery(this).scrollTop() > flash_position.top && flash_error.attr("position") != "fixed") {
            flash_error.css({
                'position': 'fixed',
                'top': "0px",
                "width": flash_error.width(),
                "z-index": "1"
            });
            place_holder.css("display", "");
        } else {
            flash_error.css('position', '');
            place_holder.css("display", "none");
        }

    }
    if (flash_error.length > 0) {
        lockErrorMessageToTop();

        jQuery("#flash_error").after(jQuery("<div id='place_holder'>"));
        var place_holder = jQuery("#place_holder");
        place_holder.css({
            "height": flash_error.height(),
            "display": "none"
        });
        jQuery(window).scroll(function(e) {
            lockErrorMessageToTop();
        });
    }
}
scrollErrorMessageToTop();​

C'est un peu plus dynamique, de manière à faire défiler. Il a besoin d'un peu de travail et je vais à un moment donné transformer cela en un plug-in mais c'est ce que j'ai inventé après des heures de travail.

0
répondu Brandt 2012-11-28 22:59:11

en javascript, vous pouvez faire:

var element = document.getElementById("myid");
element.style.position = "fixed";
element.style.top = "0%";
0
répondu htmlfarmer 2013-05-29 22:55:42

pas une solution exacte mais une excellente alternative pour considérer

ce CSS UNIQUEMENT le Haut de l'écran barre de défilement . Résolu tout le problème avec SEULEMENT CSS , NON JavaScript NON JQuery, Non Cerveau de travailler ( lol ).

Profiter mon violon : D tous les codes y sont inclus:)

CSS

#menu {
position: fixed;
height: 60px;
width: 100%;
top: 0;
left: 0;
border-top: 5px solid #a1cb2f;
background: #fff;
-moz-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
-webkit-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
z-index: 999999;
}

.w {
    width: 900px;
    margin: 0 auto;
    margin-bottom: 40px;
}<br type="_moz">

mettez le contenu assez longtemps pour que vous puissiez voir l'effet ici :) Oh, et la référence est là aussi, pour le fait qu'il mérite son crédit "151980920

CSS seulement barre de défilement du haut de l'écran

0
répondu weia design 2014-07-09 18:40:52

voici un exemple qui utilise jQuery-visible plugin: http://jsfiddle.net/711p4em4 / .

HTML:

<div class = "wrapper">
    <header>Header</header>
    <main>
        <nav>Stick to top</nav>
        Content
    </main>
    <footer>Footer</footer>
</div>

CSS:

* {
    margin: 0;
    padding: 0;
}

body {
    background-color: #e2e2e2;
}

.wrapper > header,
.wrapper > footer {
    font: 20px/2 Sans-Serif;
    text-align: center;
    background-color: #0040FF;
    color: #fff;
}

.wrapper > main {
    position: relative;
    height: 500px;
    background-color: #5e5e5e;
    font: 20px/500px Sans-Serif;
    color: #fff;
    text-align: center;
    padding-top: 40px;
}

.wrapper > main > nav {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    font: 20px/2 Sans-Serif;
    color: #fff;
    text-align: center;
    background-color: #FFBF00;
}

.wrapper > main > nav.fixed {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
}

JS (jquery comprend visible plugin):

(function($){

    /**
     * Copyright 2012, Digital Fusion
     * Licensed under the MIT license.
     * http://teamdf.com/jquery-plugins/license/
     *
     * @author Sam Sehnert
     * @desc A small plugin that checks whether elements are within
     *       the user visible viewport of a web browser.
     *       only accounts for vertical position, not horizontal.
     */
    var $w = $(window);
    $.fn.visible = function(partial,hidden,direction){

        if (this.length < 1)
            return;

        var $t        = this.length > 1 ? this.eq(0) : this,
            t         = $t.get(0),
            vpWidth   = $w.width(),
            vpHeight  = $w.height(),
            direction = (direction) ? direction : 'both',
            clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;

        if (typeof t.getBoundingClientRect === 'function'){

            // Use this native browser method, if available.
            var rec = t.getBoundingClientRect(),
                tViz = rec.top    >= 0 && rec.top    <  vpHeight,
                bViz = rec.bottom >  0 && rec.bottom <= vpHeight,
                lViz = rec.left   >= 0 && rec.left   <  vpWidth,
                rViz = rec.right  >  0 && rec.right  <= vpWidth,
                vVisible   = partial ? tViz || bViz : tViz && bViz,
                hVisible   = partial ? lViz || rViz : lViz && rViz;

            if(direction === 'both')
                return clientSize && vVisible && hVisible;
            else if(direction === 'vertical')
                return clientSize && vVisible;
            else if(direction === 'horizontal')
                return clientSize && hVisible;
        } else {

            var viewTop         = $w.scrollTop(),
                viewBottom      = viewTop + vpHeight,
                viewLeft        = $w.scrollLeft(),
                viewRight       = viewLeft + vpWidth,
                offset          = $t.offset(),
                _top            = offset.top,
                _bottom         = _top + $t.height(),
                _left           = offset.left,
                _right          = _left + $t.width(),
                compareTop      = partial === true ? _bottom : _top,
                compareBottom   = partial === true ? _top : _bottom,
                compareLeft     = partial === true ? _right : _left,
                compareRight    = partial === true ? _left : _right;

            if(direction === 'both')
                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
            else if(direction === 'vertical')
                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
            else if(direction === 'horizontal')
                return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
        }
    };

})(jQuery);

$(function() {
    $(window).scroll(function() {
        $(".wrapper > header").visible(true) ?
            $(".wrapper > main > nav").removeClass("fixed") :
            $(".wrapper > main > nav").addClass("fixed");
    });
});
0
répondu DRD 2014-10-29 22:31:47

collante jusqu'au pied de frappe de la div:

function stickyCostSummary() {
    var stickySummary = $('.sticky-cost-summary');
    var scrollCostSummaryDivPosition = $(window).scrollTop();
    var footerHeight = $('#footer').height();
    var documentHeight = $(document).height();
    var costSummaryHeight = stickySummary.height();
    var headerHeight = 83;
    var footerMargin = 10;
    var scrollHeight = 252;
    var footerPosition = $('#footer').offset().top;

    if (scrollCostSummaryDivPosition > scrollHeight && scrollCostSummaryDivPosition <= (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
        stickySummary.removeAttr('style');
        stickySummary.addClass('fixed');

    } else if (scrollCostSummaryDivPosition > (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
        stickySummary.removeClass('fixed');
        stickySummary.css({
          "position" : "absolute",
          "top" : (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin - scrollHeight) + "px"
      });
    } else {
        stickySummary.removeClass('fixed');
        stickySummary.css({
            "position" : "absolute",
            "top" : "0"
        });
    }
}

$window.scroll(stickyCostSummary);
-1
répondu Ottens 2016-11-18 07:05:38