Search code examples
cssflexboxcss-positionsticky

CSS position sticky cross browser solution


I have a layout that is structured from 1 header and 3 vertical panels. All vertical panels can be horizontally expanded/contracted and need to fill up together 100% width of the page. The panels also need to take 100% of the vertical space after the header (the header has an automatic height).

Each panel by itself need to be scrollable without scrolling the whole page or affecting the other panels position on the page.

enter image description here enter image description here

The problem that I am facing is that the panels need to act both as relative positioning horizontally (so that they fill up 100% width together) but also as a fixed positioning vertically so that they stay put when scrolling.

If I use position:sticky it works good but is not supported by Chrome/Opera and therefore not an option. If I use javascript, I'm having other issues when contracting/expanding since they have also animation and it just looks bad. While I can make it work, Javascript is not my desired solution at all. I'm trying to find a pure CSS cross browser solution for it.

It is important that each panel stays scrollable without scrolling the whole page and of course have a "sticky" behavior.

I'm not a CSS expert so there probably is a simple solution that I'm missing. Thanks.


Solution

  • Here is one way, using flexbox

    html, body {
      margin: 0;
      height: 100%;
    }
    
    .flexwrapper {
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    
    .flexheader {
      flex: 0;
      padding: 10px;
      background: #f93;
      text-align: center;
    }
    
    .flexcontent {
      flex: 1;
      display: flex;
    }
    
    .flexinner {
      flex: 1;
      background: #09f;
      margin: 1px;
      position: relative;
    }
    
    .absscroll {
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      overflow: auto;
    }
    <div class="flexwrapper">
    
      <div class="flexheader">
        Header
      </div>
    
      <div class="flexcontent">
    
        <div class="flexinner">
          <div class="absscroll">
    
          </div>
        </div>
    
        <div class="flexinner">
          <div class="absscroll">
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
    Bla bla<br>
          </div>
        </div>
        
        <div class="flexinner">
          <div class="absscroll">
    
          </div>
        </div>
    
      </div>
    
    </div>