Problem securing side column when scroll is larger than its height

Asked

Viewed 124 times

2

I have a layout with a main div and inside it 2 Divs, each one being a column:

body{
   margin: 0;
}

#principal{
   display: flex;
   width: 80%;
   margin: 0 auto;
   position: relative;
}

#conteudo{
   width: calc(100% - 330px);
   height: 1500px;
   background-color: orange;
   margin-right: 30px;
}

#lateral{
   position: relative;
   width: 300px;
   height: 1100px;
   background-color: red;
   bottom: 0;
   right: 0;
}

#lateral span{
   position: absolute;
   bottom: 0;
   left: 0;
}
<div id="principal">
   <div id="conteudo">
      conteúdo
   </div>
   <div id="lateral">
      coluna lateral
      <span>fim da coluna lateral</span>
   </div>
</div>

When scrolling down, note that the div to the right (red) is smaller than the div to the left (orange).

The goal is for the red column to follow the scroll of the page normally, but when its end (bottom edge), once it enters the browser window area, it stops scrolling next to the window and becomes fixed (same behavior of Facebook’s right side column on desktop); and when scrolling the document back up, it goes back to normal by following the window scroll again.

I even managed to make programmatic logic with Javascript, but the problem is that by changing the property position from the div to fixed, she runs away from the main div, because the value fixed is related to the body, and not to its container, distorting the layout.

Behold:

window.onscroll = function(){

   // posição do scroll
   var scrol = window.pageYOffset;
   
   // altura do documento
   var w_alt = window.innerHeight;
   
   // pega a lateral
   var lat = document.getElementById("lateral");

   // altura coluna lateral
   var l_alt = lat.clientHeight;

   // se o valor do scroll for maior do que a diferença
   // da altura da lateral pela altura da janela
   if(scrol > l_alt - w_alt){
      
      // torna a lateral fixa
      lat.style.position = "fixed";
      
   }else{

      // volta para relative
      lat.style.position = "relative";

   }
   
}
body{
   margin: 0;
}

#principal{
   display: flex;
   width: 80%;
   margin: 0 auto;
   position: relative;
}

#conteudo{
   width: calc(100% - 330px);
   height: 1500px;
   background-color: orange;
   margin-right: 30px;
}

#lateral{
   position: relative;
   width: 300px;
   height: 1100px;
   background-color: red;
   bottom: 0;
   right: 0;
}

#lateral span{
   position: absolute;
   bottom: 0;
   left: 0;
}
<div id="principal">
   <div id="conteudo">
      conteúdo
   </div>
   <div id="lateral">
      coluna lateral
      <span>fim da coluna lateral</span>
   </div>
</div>

How could I get this div fixed the way up but not get out of position inside the div #principal, that it simply stayed fixed when the scroll reached its height?

Note: must be in pure Javascript.

  • What browser support? Has to work in explorer? and edge mobile?

  • Hi @Andersonhenrique! No problem with support. Working on Chrome is already great.

1 answer

1


Sam I have a solution for you. I don’t know if it was exactly what you wanted, but it will solve only with JS. You might be able to do it in CSS, but since you already have script put the style in itself.

As you said, the element with position:fixed shall relate to body, however its container is 80% wide body, logo vc has 10% left margin and 10% right margin. So the idea is that at the same time you arrow the position:fixed I also know the marginRight 10%, with that he does not "run away" from container father.

inserir a descrição da imagem aqui

See the code

window.onscroll = function () {

  // posição do scroll
  var scrol = window.pageYOffset;

  // altura do documento
  var w_alt = window.innerHeight;

  // pega a lateral
  var lat = document.getElementById("lateral");

  // altura coluna lateral
  var l_alt = lat.clientHeight;

  // se o valor do scroll for maior do que a diferença
  // da altura da lateral pela altura da janela
  if (scrol > l_alt - w_alt) {

    // torna a lateral fixa
    lat.style.position = "fixed";
    lat.style.marginRight = "10%";

  } else {

    // volta para relative
    lat.style.position = "relative";
    lat.style.marginRight = "initial";

  }

}
body {
  margin: 0;
}

#principal {
  display: flex;
  width: 80%;
  margin: 0 auto;
  position: relative;
}

#conteudo {
  width: calc(100% - 330px);
  height: 1500px;
  background-color: orange;
  margin-right: 30px;
}

#lateral {
  position: relative;
  width: 300px;
  height: 1100px;
  background-color: red;
  bottom: 0;
  right: 0;
}

#lateral span {
  position: absolute;
  bottom: 0;
  left: 0;
}
<div id="principal">
  <div id="conteudo">
    conteúdo
  </div>
  <div id="lateral">
    coluna lateral
    <span>fim da coluna lateral</span>
  </div>
</div>

  • So simple and I didn’t think of it rs.. Thanks!

  • @Sam was so simple that I was even in doubt if that’s what you wanted rss. []s

  • 1

    Sometimes the simplest things escape our perception. : D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.