Home > Mobile >  Fix Element at Bottom of the Screen, but only as long as the Parent Container hasn't ended?
Fix Element at Bottom of the Screen, but only as long as the Parent Container hasn't ended?

Time:10-27

Say I have an element that is visually part of a container. This container can be very long in height.

Now when the user scrolls down, I want to position this element to remain at the bottom of the screen. But when the container ends at some point, I want the element to stay at the bottom of that container and no scroll down further.

So once again: When the container hasn't ended yet, the element is at the bottom of the screen:

enter image description here

... but when I continue scrolling, it stops inside the container:

enter image description here

I am a bit stuck here. I do know how to do this when the element is positioned at the top inside of the container. Scrolling down will then just make it stop at the bottom.

The problem seems to be that either the Element will be moved outside of the document flow, so it won't remain inside the container, OR it will be at the bottom of the container all the time, so the element won't scroll with the user and remain on the bottom of the screen.

Any ideas?

<div className="mx-20 my-36">
    <div className="bg-slate-200 h-[1200px] w-full relative border-2 border-black relative">
        <div className="fixed bottom-0 left-0 right-0 p-2 bg-white w-full border-2 border-red-600">Element</div>
    </div>

    <div className="my-12">

        The page continues here but the element remains in the container ...
    </div>
</div>

PS: Using tailwind & react here, but any vanilla CSS are welcome too! I would love to solve this without javascript.

CodePudding user response:

  1. Create a parent div around both elements. Move all styles to this parent except for the height.
  2. Switch out fixed for sticky
  3. You can remove relative - it doesn't do anything anymore
<div className="mx-20 my-36">
  <div className="bg-slate-200 border-2 border-black w-full">
    <div className="h-[1200px]">
    </div>
    <div className="sticky bottom-0 left-0 right-0 p-2 bg-white w-full border-2 border-red-600">Element</div>
  </div>

  <div className="my-12">
    The page continues here but the element remains in the container ...
  </div>
</div>

DEMO: https://play.tailwindcss.com/gy71xPcjnR

CodePudding user response:

Your issue is technically your solution. Position: sticky will only stay within a parent element. The best way to fix this is to place a parent element around alllll objects you want the sticky to scroll over. If that doesn't work, you could use jquery or javascript to write a script that says, "when the viewport scrolls to this position, then add position:fixed to this element"

Position: Sticky makes an element appear at the top of the parent container, then scroll over everything else in a fixed position (literally like position: fixed) until the end of the parent container.

To make this work you need to:

  1. start a parent container at the place where you want the sticky item to first appear
  2. contain all of the items you want the sticky object to scroll over inside that parent container
  3. end the parent container where you want the sticky object to stop

Here's another SO post about it: CSS: Position sticky to bottom when enter viewport

.sticky {
  position: -webkit-sticky;
  position: sticky;
  bottom: 0;
  height: 30px;
  width: 100vw;
  background: yellow;
}
<!-- Content you want before the sticky element -->
<div>
  <div style="height: 300px; background: red;">Scroll</div>
  <div style="height: 300px; background: orange;"></div>
</div>

<!-- Content you want after the sticky element -->
<div>
  <!-- The sticky element will appear as if its been placed here -->
  <div style="height: 300px; background: green;"></div>
  <div style="height: 300px; background: blue;"></div>
    <div style="height: 300px; background: red;">Scroll</div>
  <div style="height: 300px; background: orange;"></div>
    <div style="height: 300px; background: red;">Scroll</div>
  <div style="height: 300px; background: orange;"></div>
    <div style="height: 300px; background: red;">Scroll</div>
  <div style="height: 300px; background: orange;"></div>
  <div >Sticky Section</div>
</div>

if you want to go the jquery route...

$(document).scroll(function() {
  var viewportPlacement = $(window).scrollTop()   $(window).height(); //finds the height of the bottom of the viewport
  var initialSticky = $('.sticky').prev().height()   $('.sticky').height(); //finds the initial placement of the sticky element, plus the height of the element so the whole thing has to scroll into view for the fixed position to be added
  if (viewportPlacement >= initialSticky) { //if the bottom of the viewport has the whole sticky element in it
    $('.sticky').css('position', 'fixed') //then add position fixed to it
  } else if (viewportPlacement < initialSticky){ //else if the initial placement of the sticky element is below the viewport
    $('.sticky').css('position', 'static') //remove the position fixed
  }
})
.sibling {
    background-color: lavender;
    height: 150vh;
}

.sticky {
    background-color: pink;
    box-sizing: border-box;
    border: 1px solid fuchsia;
    position: static;
    padding: 20px;
    width: 100%;
    bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div ></div>
<div >Hello World</div>
<div ></div>

  • Related