Search code examples
htmlcssscrollflexboxcss-position

Remove white space created by relative placed div OR place div's on top of each other while preserving scroll


I have a pretty specific website design in which I place horizontal bars over a date/time scale. The date scale needs to scroll horizontally while I'm also able to vertically scroll through the bars.

I have the following codepen to show the situation: codepen

The hScroll div needs to scroll horizontally. the content div needs to scroll vertically.

The html looks like this:

<div class="main">
  <div class="header">   
    <div>HEADER</div>  
  </div>
  <div class="hScroll">
    <div class="dates">
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>
    <div class="content">
      <div class="bars">
        <div></div>
        <div class="wk"></div>
        <div></div>
      </div>
      <div class="overlay">
        <div style="top: 20px; left: 200px;"></div>
        <div style="top: 400px; left: 1200px;"></div>
      </div>
    </div>
  </div>
</div>

The css

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
.main {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.header {
  height: 45px;
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #3c5db2;
  color: rgb(240,240,240);
}
.hScroll {
  display: flex;

  flex-direction: column;
  flex-grow: 1;
  background-color: rgb(200,200,200);
  overflow-x: scroll;
}
.dates {
  display: flex;
  width: 2000px;
  height: 30px;
  background-color: rgb(66, 133, 244);
}
.dates > div {
  padding: 5px;
  height: 100%;
  width: 200px;
  border-right: solid 2px rgb(240,240,240);
  color: rgb(240,240,240);
}
.content {
  flex-grow: 1;
  width: 2000px;
  overflow-y: scroll;
  font-size: 1.5em;
  line-height: 3em
}
.bars {
  display: flex;
}
.bars > div {
  width: 200px;
  border-right: solid 2px rgb(240,240,240);
  height: 1000px;
}
.overlay {
  position: relative;
  top: -1000px;  
}
.overlay div {
  position: relative;
  height: 20px;
  width: 250px;
  background-color: red;
}
.wk {
  background-color: rgb(220,220,220);
}

Is there a way to create the same result without using "position: relative"?

If not, how to fix the white (in this case green) space at the end of content div?

With all the scrolling going on and the precise positioning of the bars it's hard to find a fitting solution on the web. Any help is very much appreciated!


Solution

  • try like below,

    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    .main {
      width: 100vw;
      height: 100vh;
      display: flex;
      flex-direction: column;
    }
    .header {
      height: 45px;
      flex-shrink: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #3c5db2;
      color: rgb(240,240,240);
    }
    .hScroll {
      display: flex;
    
      flex-direction: column;
      flex-grow: 1;
      background-color: rgb(0,255,0);
      overflow-x: scroll;
    }
    .dates {
      display: flex;
      width: 2000px;
      height: 30px;
      background-color: rgb(66, 133, 244);
    }
    .dates > div {
      padding: 5px;
      height: 100%;
      width: 200px;
      border-right: solid 2px rgb(240,240,240);
      color: rgb(240,240,240);
    }
    .content {
      flex-grow: 1;
      width: 2000px;
      overflow-y: scroll;
      font-size: 1.5em;
      line-height: 3em
    }
    .bars {
      display: flex;
    }
    .bars > div {
      width: 200px;
      border-right: solid 2px rgb(240,240,240);
      height: 1000px;
      background-color: lightgrey;
    }
    .overlay {
      position: relative;
      top: -1000px;  
    }
    .overlay div {
      position: absolute;
      height: 20px;
      width: 250px;
      background-color: red;
    }
    .wk {
      background-color: rgb(220,220,220);
    }
    <div class="main">
      <div class="header">   
        <div>HEADER</div>  
      </div>
      <div class="hScroll">
        <div class="dates">
          <div>1</div>
          <div>2</div>
          <div>3</div>
          <div>4</div>
          <div>5</div>
          <div>6</div>
          <div>7</div>
          <div>8</div>
          <div>9</div>
          <div>10</div>
        </div>
        <div class="content">
          <div class="bars">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div class="wk"></div>
            <div class="wk"></div>
            <div></div>
            <div></div>
            <div></div>
          </div>
          <div class="overlay">
            <div style="top: 20px; left: 200px;"></div>
            <div style="top: 100px; left: 400px;"></div>
            <div style="top: 200px; left: 700px;"></div>
            <div style="top: 300px; left: 900px;"></div>
            <div style="top: 400px; left: 1200px;"></div>
          </div>
          
        </div>
      </div>
    </div>