[Main Content]
EDIT – solution jQuery (css original seulement réponse ci-dessous):
Sur la base des modifications de votre question qui apportent des contraintes supplémentaires et compliquent un peu la solution de type html / css, voici une solution jQuery utilisant votre code avec une nouvelle méthode jQuery pour le widget sticky sidebar et css pour définir la position: absolute
et right: 30px
(cette valeur est arbitraire en fonction de l’endroit où vous souhaitez que le widget se trouve dans la barre latérale). Vous avez également commenté quelques autres lignes css qui ne faisaient rien ou qui gênaient la réactivité de votre présentation en grid (la fonctionnalité de la barre latérale collante fonctionne avec ou sans ces modifications, bien que vous puissiez avoir besoin d’ajuster la right
css de votre élément de widget, y compris les requêtes multimédias, en fonction de l’emplacement de votre mise en page)
$(function() { const sidebar = $('.sidebar-container'); const widget = $('.widget'); const footer = $('.footer'); const space = 10; // arbitrary value to create space between the window and widget const startTop = sidebar.offset().top + 60; // arbitrary start top position const endTop = footer.offset().top - widget.height() - space; widget.css('top', startTop); $(window).scroll(function() { let windowTop = $(this).scrollTop(); let widgetTop = widget.offset().top; let newTop = startTop; if (widgetTop >= startTop && widgetTop <= endTop) { if (windowTop > startTop - space && windowTop < endTop - space) { newTop = windowTop + space; } else if (windowTop > endTop - space) { newTop = endTop; } widget.stop().animate({ 'top': newTop }); } }); });
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); * { font-family: 'Open Sans'; color: #fff; box-sizing: content-box; } body { padding: 0; margin: 0; } p { margin: 20px; } hr { width: 85%; border-style: solid; } .main-content { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 150px auto; grid-template-areas: "nav nav nav nav" "main main main sidebar"; grid-column-gap: 20px; grid-row-gap: 0px; } .nav { grid-area: nav; background-color: #266392; display: grid; grid-template-columns: 1fr 3fr 1fr; } .nav h1 { place-self: center; font-weight: 400; font-size: 40px; grid-column: 2; } .nav i { align-self: center; font-size: 40px; } .main { height: 1500px; /*width: 98%; justify-self: start;*/ grid-area: main; padding: 10px; /*float: left;*/ background-color: #e8624c; margin: 10px; } .sidebar-container { height: 900px; width: 300px; justify-self: end; background-color: #209B66; grid-area: sidebar; grid-column: 4; /*top: 10px;*/ margin: 10px; padding: 20px; display: grid; grid-template-rows: auto; grid-row-gap: 10px; } .sidebar-container>p { display: grid; align-items: start; padding: 0; margin: 0; } .widget { height: 500px; width: 300px; background-color: #E3962F; position: absolute; right: 30px; } .footer { background-color: #333; height: 800px; }
[Main Content]
Nous pouvons diviser cela en 2 problèmes différents. Problème n ° 1, vous avez besoin de l’accord en Y du bas de votre élément (a), et problème n ° 2, du bas de la page (b). Si vous avez ces données, votre réponse est simplement (b – a).
Pour nous aider, créons une fonction d’assistance en tant que telle:
function getOffset(el) { const rect = el.getBoundingClientRect(); return { left: rect.left + window.scrollX, right: rect.left - window.scrollX, top: rect.top + window.scrollY, bottom: rect.bottom -window.scrollY }; }
Avec cela, cela devrait être aussi simple que getOffset(document.body).bottom - getOffset(yourElement).bottom
.
J’espère que cela t’aides!
(Notez que je ne peux pas réellement tester ce code maintenant, donc il risque de ne pas fonctionner immédiatement, utilisez-le plutôt comme guide et non comme un copier / coller).