4

I want to make a div sticky to scrolling, but when it will always stay at the top of the footer.

I tried using position:sticky which works fine, but it doesn't work on IE11.

I also tried multiple solutions for similar issue but they always referring on how to make the footer sticky and not another <div> inside the main <div>.

This is how my code looks:

.slider {
  background: #006264;
  color: white;
  position: sticky;
  bottom: 0px;
  width: 100%;
  height: 60px;
}

.footer {
  background: #04246A;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  height: 119px;
}
<div class="main">
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="slider">
    This is the footer
  </div>
</div>
<div class="footer">This is the main footer</div>

Here it is on JSFiddle

How can I solve this?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Renaud is Not Bill Gates
  • 1,684
  • 34
  • 105
  • 191
  • 2
    Have you tried the answer from [this question?](https://stackoverflow.com/questions/37646066/position-sticky-buttons-not-working-in-ie-11) – node_modules Oct 20 '20 at 19:02
  • Yes, as I said before I tried other solutions which is about making the footer sticky, in that example the div that is sticky is the last one in the dom, making it to act like the footer means there is nothing under it, in my example I have a footer under the div that I want to make sticky, so using `position: fixed` will make it sticky but it will always hide the footer. – Renaud is Not Bill Gates Oct 20 '20 at 19:28
  • 1
    Funny, [this looks familiar](https://jsfiddle.net/TylerH/gv9ugaw9/178/)... – TylerH Oct 26 '20 at 19:46

6 Answers6

2

Unfortunately I am not aware of any CSS-only method to achieve such an effect. However, it is, of course, possible with JavaScript and some additional CSS. I used jQuery in my example because it is easier to understand but you can convert it to JS of course.

$(window).scroll(function() {
  if ($(window).scrollTop() + $(window).height() > $('.footer').offset().top) {
    $('.main').removeClass('fixed');
  } else {
    $('.main').addClass('fixed');
  }
});

$(window).scroll();
/* resets */

body {
  margin: 0px;
  padding: 0px;
}

.main.fixed>.slider {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
}

.main.fixed~.footer {
  margin-top: 60px;
}

.slider {
  background: #006264;
  color: white;
  width: 100%;
  height: 60px;
}

.footer {
  background: #04246A;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  height: 119px;
}

.placeholder {
  padding: 100px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="main fixed">
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="slider fixed">
    This is the footer
  </div>
</div>
<div class="footer">This is the main footer</div>

And yes, it works in IE since jQuery still supports IE9+. Remember that this is a basic example and you should work on some performance enhancements.

Aaron3219
  • 2,168
  • 4
  • 11
  • 28
1

Writing some few lines of JavaScript should do the trick for this requirement. We can have the main footer as our indicator if we should have the sub footer position: fixed or position: relative based on the current window scroll position - this is what sticky is after all, i.e., a hybrid of fixed & relative.

In my solution below, the general advantage is that the event listener for scroll only kicks in when the client is using IE11. I've found that IE11 actually removes the sticky position style on the DOM since it does not support it.

In short, moderns browsers are still going to use sticky and the below code is simply backup when the user is on IE11.

<!-- place the style inline to cater the condition statement -->
<div class="slider" style="position: sticky;">

.slider {
  background: #006264;
  color: white;
  position: fixed; /* fixed is for the IE11 fallback */
  bottom: 0px;
  width: 100%;
  height: 60px;
}

// IE11 actually removes "sticky" from attribute "styles" value. So at this point we can control when to add an event listener (i.e., Modern browsers will still use position: sticky)
if (divFooter.style.position != "sticky") {
  window.addEventListener("scroll", function() {
    if (mainFooter.getBoundingClientRect().top - window.innerHeight <= 0) {
      divFooter.style.position = "relative";
      mainFooter.style.marginTop = "0";
    } else if (mainFooter.getBoundingClientRect().top - window.innerHeight > 0) {
      divFooter.style.position = "fixed";
      mainFooter.style.marginTop = divFooter.clientHeight.toString() + "px";
    }
  })
}

var divFooter = document.querySelector(".slider");
var mainFooter = document.querySelector(".footer");

// IE11 actually removes "sticky" from attribute "styles" value. So at this point we can control when to add an event listener (i.e., Modern browsers will still use position: sticky)
if (divFooter.style.position != "sticky") {
  window.addEventListener("scroll", function() {
    if (mainFooter.getBoundingClientRect().top - window.innerHeight <= 0) {
      divFooter.style.position = "relative";
      mainFooter.style.marginTop = "0";
    } else if (mainFooter.getBoundingClientRect().top - window.innerHeight > 0) {
      divFooter.style.position = "fixed";
      mainFooter.style.marginTop = divFooter.clientHeight.toString() + "px";
    }
  })
}
html,
body {
  margin: 0;
}

.placeholder {
  border: 1px solid black;
  margin: 0 auto;
  text-align: center;
  height: 300px;
}

.slider {
  background: #006264;
  color: white;
  position: fixed;
  bottom: 0px;
  width: 100%;
  height: 60px;
}

.footer {
  background: #04246A;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  height: 119px;
}
<div class="main">
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="slider" style="position: sticky;">
    This is the footer
  </div>
</div>
<div class="footer">This is the main footer</div>

As far as a pure CSS solution - here is what I've got: you can opt to have 2 scrollbars. 1 for the body & 1 for main - we can hide the horizontal scrollbar for aesthetics.

body {
  overflow-x: hidden;
}

.main {
  max-height: calc(100vh - 60px);
  overflow-y: scroll;
  width: 100vw;
}

html,
body {
  margin: 0;
}

.placeholder {
  border: 1px solid black;
  margin: 0 auto;
  text-align: center;
  height: 300px;
}

.slider {
  background: #006264;
  color: white;
  /* position: sticky; */
  bottom: 0px;
  width: 100%;
  height: 60px;
}

.footer {
  background: #04246A;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  height: 119px;
}

body {
  overflow-x: hidden;
}

.main {
  max-height: calc(100vh - 60px);
  overflow-y: scroll;
  overflow-x: hidden;
  width: 100vw;
}
<div class="main">
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
</div>
<div class="slider">
  This is the footer
</div>
<div class="footer">This is the main footer</div>

Below you can find the inner workings of the CSS implementation minus the hiding of the scrollbar. This is pretty hacky - if you can find a way for the scrolling to prioritize the body on-scroll-up, that will do best for your system.

html,
body {
  margin: 0;
}

.placeholder {
  border: 1px solid black;
  margin: 0 auto;
  text-align: center;
  height: 300px;
}

.slider {
  background: #006264;
  color: white;
  /* position: sticky; */
  bottom: 0px;
  width: 100%;
  height: 60px;
}

.footer {
  background: #04246A;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  height: 119px;
}

body {
  /* overflow-x: hidden; */
}

.main {
  max-height: calc(100vh - 60px);
  overflow-y: scroll;
  /* width: 100vw; */
}
<div class="main">
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
</div>
<div class="slider">
  This is the footer
</div>
<div class="footer">This is the main footer</div>
95faf8e76605e973
  • 13,643
  • 3
  • 24
  • 51
1

If you want to use CSS only solution and are fine with slider staying fixed in IE, you can use IE only style to set fixed position for slider and setting margin-bottom for footer.

html,
body {
  margin: 0;
}

.placeholder {
  border: 1px solid black;
  margin: 0 auto;
  text-align: center;
  height: 300px;
}

.slider {
  background: #006264;
  color: white;
  position: sticky;
  bottom: 0px;
  width: 100%;
  height: 60px;
}

.footer {
  background: #04246A;
  color: white;
  font-weight: bold;
  margin: 0 auto;
  height: 119px;
}

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
  /* IE10+ CSS */
  .slider {
    position: fixed;
  }
  .footer {
    margin-bottom: 60px;
  }
}
<div class="main">
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="placeholder">This div holds place</div>
  <div class="slider">
    This is the footer
  </div>
</div>
<div class="footer">This is the main footer</div>
Dipen Shah
  • 25,562
  • 1
  • 32
  • 58
0

Based on https://developer.mozilla.org/en-US/docs/Web/CSS/position, (Refer - Browser Compatibility at documentation End) position sticky doesn't seem to be supported by IE11.

So you might have to try doing it using Specificity Hierarchy of the styling. You can specify your CSS property - sticky to be inline to have a higher Hierarchy and if it is not supported then you can substitute it with the lower Specificity Hierarchy CSS property.

Additionally you can add below code for Safari.

.slider {
        position: -webkit-sticky; /* Safari */
        position: sticky;
        bottom: 0;    
       }
0

You can use position: fixed in CSS. Feel free to copy this:

<html>
    <head>
        <style>
            .sticky {
                position: fixed;/*this makes it work!*/
                width: 100vw;
                height: 10vh;
                text-align: center;
                background-color: green;
                bottom: 0px;
                color: white;
                font-size: 40px;
            }
            .body1 {
                height: calc(100vh - 80px);
                width: calc(100vw - 80px);
                border: 10px solid black;
                text-align: center;
                font-size: 100px;
            }
            .this {
                margin-bottom: 10vh;
                /*this is some style*/
            }
        </style>
    </head>
    <body>
        <div class="body1">content</div>
        <div class="body1">content</div>
        <div class="body1">content</div>
        <div class="body1">content</div>
        <div class="body1">content</div>
        <div class="body1">content</div>
        <div class="body1">content</div>
        <div class="body1 this">content</div>
        <div class="sticky">I am sticky!</div>
    </body>
</html>
Green
  • 486
  • 2
  • 11
  • 31
0

Since position: sticky is not supported by IE11 i would propose stickybits.

Taken from stickybits documentation:

Stickybits is a lightweight alternative to position: sticky polyfills. It works perfectly for things like sticky headers.

Regarding browser compatibility:

Stickybits works in all modern browsers including Internet Explorer 9 and above. Please file and issue with browser compatibility quirks.

An example based on your Fiddle.