Search code examples
htmlcsssvgscroll

Scrollable svg content


I'm trying to implement a layout with a vertical scroll.

Suppose I have something like this:

enter image description here

The gray area contains a lot of information (the green rectangles) so its height is for example 1000px. The gray area is an svg.

Then I need to visualize only a small part if the gray area. This is rapresented as the yellow area (for example of height 400px). So the yellow rectangle is like a window of the visible gray area. The yellow container contains a blue rectangle that should be always on the bottom og the yellow area.

This should be the result when user scrolls vertically:

enter image description here

Here is my code:

.container {
  border: 1px solid black;
}

.container-inner {
  width: 300px;
  background-color: #f3f8fc;
}

.container-content {
  position: relative;
  width: 100%;
  height: 300px;
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid yellow;
  background-color: lightyellow;
}

svg {
  border: 1px solid gray;
}

.footer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 50px;
  border: 1px solid skyblue;
  background-color: paleturquoise;
}
<div class="container">
  <div class="container-inner">
    <div class="container-content">
      <svg x="0" y="0" width="300" height="1000">
        <rect x="0" y="0" width="300" height="1000" fill="lightgray" />
        <rect x="10" y="10" width="280" height="200" fill="green" fill-opacity="0.3" />
        <rect x="10" y="220" width="280" height="100" fill="green" fill-opacity="0.3" />
        <rect x="10" y="340" width="280" height="350" fill="green" fill-opacity="0.3" />
        <rect x="10" y="700" width="280" height="290" fill="green" fill-opacity="0.3" />
      </svg>
      
      <div class="footer" />
    </div>
  </div>
</div>

As you can see it doesn't work as I'm expecting: the cyan rectangle is moving with the scroll instead of remains on the bottom of the yellow container. Why?

Is there a smarter solution to do what I need?

NOTE: The content in the grey rectangle must be svg.


Solution

  • So close! position: sticky on the footer will sort you out!

    .container {
      border: 1px solid black;
    }
    
    .container-inner {
      width: 300px;
      background-color: #f3f8fc;
    }
    
    .container-content {
      position: relative;
      width: 100%;
      height: 300px;
      max-height: 300px;
      overflow-y: auto;
      border: 1px solid yellow;
      background-color: lightyellow;
    }
    
    svg {
      border: 1px solid gray;
    }
    
    .footer {
      position: sticky;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 50px;
      border: 1px solid skyblue;
      background-color: paleturquoise;
    }
    <div class="container">
      <div class="container-inner">
        <div class="container-content">
          <svg x="0" y="0" width="300" height="1000">
            <rect x="0" y="0" width="300" height="1000" fill="lightgray" />
            <rect x="10" y="10" width="280" height="200" fill="green" fill-opacity="0.3" />
            <rect x="10" y="220" width="280" height="100" fill="green" fill-opacity="0.3" />
            <rect x="10" y="340" width="280" height="350" fill="green" fill-opacity="0.3" />
            <rect x="10" y="700" width="280" height="290" fill="green" fill-opacity="0.3" />
          </svg>
          
          <div class="footer" />
        </div>
      </div>
    </div>