1

I want to make a fixed element (like sticky) when I scroll and reach the top of another element. The fixed element will increase the bottom property of css to don't pass the top of the element I set as bound (the element you can't pass the point, like a ground). I did a pen that shows what I want, hope that helps: https://codepen.io/vendramini/pen/xNWpPK. I really don't know which calculation I need to do to achieve this. Please, help me.

https://codepen.io/vendramini/pen/xNWpPK The best I could do to exemplify this.


*{
  margin: 0;
  padding: 0;
}

section{
  height: 100vh;
  width: 100vw;
  background: #eee;
  position: relative;
  max-width: 100%;
}

.a{
  background: #faa;
}

.b{
  background: #ffa;
}

.c{
  background: #afa;
}

.d{
  background: #aaf;
}

.sticky{
  width: 100%;
  position: fixed;
  height: 100px;
  background: blue;
  opacity: 0.5;
  bottom: 0;
  z-index: 1;
}

.ground{
    height: 2000px;
    background: black;
}
//jQuery required

(function($){

  $('[data-bound]').each(function(){

    const $elem = $(this);
    const $bound = $( $elem.data('bound') );

    $(window).scroll(function(){

      const scrollTop = $(window).scrollTop();
      const boundTop = $bound.offset().top;
      const boundHeight = $bound.height();
      const delta = (scrollTop - boundTop); //+ boundHeight;

      console.log({
        scrollTop,
        boundTop,
        delta,
      });

      if( delta > 0 ){
        $elem.css('bottom', delta);
      }
      else{
        $elem.removeAttr('style');
      }

    });


  });

})(jQuery);

<div class="sticky" data-bound="#ground"></div>

<section class="a"></section>
<section class="b"></section>
<section class="c"></section>
<section class="d"></section>
<footer class="ground" id="ground"></footer>
<section class="a"></section>
<section class="b"></section>
<section class="c"></section>
<section class="d"></section>


I expect to have a fixed element that doesn't pass the ground element. That's it.

  • What's the idea ? set some background to show like your past the sky and digging into the ground ? Could it be a background-position/attachement or an absolute pseudo-element attached from the ground so it slides with it ? to size the pseudo it might be the difference from the height of the document minus ground's position i guess ? – G-Cyrillus May 24 '19 at 14:29
  • It's not a background, it's a normal element (it's a fixed div with bottom:0), so when it reaches ground, the position of this element(bottom property of css will increase to don't let the element pass the ground element, remember, it's a fixed element). – Lucas Vendramini May 24 '19 at 14:34
  • imagine a stone falling in the ground (the scroll is the movement of that falling, like a camera), when the stone(fixed element) reaches the ground, it stop falling( the element still fixed but the position changes relative to the ground), thats it – Lucas Vendramini May 24 '19 at 14:36
  • Document minus ground position? Show me a example of this working. – Lucas Vendramini May 24 '19 at 14:37

4 Answers4

1

I'm not sure I understand exactly what you want, but I think you can achieve this with only CSS using position: sticky on the footer.

https://codepen.io/anon/pen/jozzPq

the relevante changes:

add a wrapper to the elements with the sticky footer:

<div>
  <section class="a"></section>
  <section class="b"></section>
  <section class="c"></section>
  <section class="d"></section>
  <footer class="ground" id="ground">   </footer>
</div>

position the footer at the bottom and set it to sticky

.ground{
    height: 100px;
    background: black;
    position: sticky;
    bottom: 0;
}

Check the codepen cause a lot of CSS and (all) JS can be removed.

arieljuod
  • 15,460
  • 2
  • 25
  • 36
  • Sticky is great, you did exacly what I want but It doesn't reach all browsers I want: https://caniuse.com/#search=sticky. I would like to do it using jQuery calculating the bottom property of fixed element. Thanks anyway! – Lucas Vendramini May 24 '19 at 13:15
  • 1
    You could use this for the browsers that support `position: sticky` and a js fallback if the browser does not support it. You can do `if (!CSS.supports('position','sticky')) {...}` in your js code, it will be more performant on the browsers that do support it, you'll have most of the problem solved with this (I guess that extra div wrapper I've added so sticky works will help you with the calculations too) – arieljuod May 24 '19 at 17:58
1

I finally found the answer:

https://codepen.io/vendramini/pen/xNWpPK

The solution is add the window's height in to the delta calculation:

const windowHeight = $(window).height();
const delta = (scrollTop - boundTop) + windowHeight;

Thanks everyone that contributed to this thread!

0

Replace

      if( delta > 0 ){
        $elem.css('bottom', delta);
      }
      else{
        $elem.removeAttr('style');
      }

with

$elem.css('bottom', 0);

to stick the element always to the bottom.

Sirisha
  • 141
  • 4
  • Thanks for reply, but It's not mandatory that the element always will have bottom: 0, I let it free to decide it via css. So I remove the inline style tag. Anyway, that doesn't influence in the resolution of the problem. – Lucas Vendramini May 24 '19 at 13:03
-2

The thing that I want is next to what UIKit does: https://getuikit.com/docs/sticky

But the problem is that UIKit uses top instead of bottom.