Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make a div sticky in IE and in top of footer

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?

like image 688
Renaud is Not Bill Gates Avatar asked Sep 18 '20 14:09

Renaud is Not Bill Gates


People also ask

How do you make a div stick to the top?

The vertical position of the element to be stuck can also be modified with the help of the 'top' property. It can be given a value of '0px' to make the element leave no space from the top of the viewport, or increased further to leave space from the top of the viewport.

How do I make a div in a div sticky?

Try introducing a wrapper div around the tag - this way you can separate the positioning logic on the wrapper, and set the tag to position: fixed; for stickiness. Note that position: fixed; by itself on the tag will pull it out of its normal dom flow, so you need to adjust its positioning.

Does position sticky work in IE?

Position Sticky doesn't work in IE but there's a solution position: sticky is extremely useful when you build a web page, but it's not supported by every browser.

Why is my div not sticky?

That can happen for many reasons: Position sticky will most probably not work if overflow is set to hidden, scroll, or auto on any of the parents of the element. Position sticky may not work correctly if any parent element has a set height. Many browsers still do not support sticky positioning.


3 Answers

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.

like image 152
Aaron3219 Avatar answered Oct 18 '22 22:10

Aaron3219


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>
like image 34
95faf8e76605e973 Avatar answered Oct 18 '22 21:10

95faf8e76605e973


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>
like image 1
Dipen Shah Avatar answered Oct 18 '22 20:10

Dipen Shah