2

I am trying to construct a simple timeline event div in HTML/CSS. It's basically just a colored rectangle with some text inside (a title). The timeline scrolls horizontally.

The thing that I don't seem to be able to figure out is how to keep the title of the event div in view when the timeline is scrolled. I would like the title to move all the way to the right and even outside the container so that it stays visible as long as the container div is in view. Is that possible at all in CSS?

This is what I have so far:

<html>
<style>
    .dummy_timeline {
        width:5000px;
        top:0px;
        left:0px;
        height:20px;
        background: linear-gradient(90deg, #222 1%, transparent 1%) 1px 0, #fff;
        background-size: 200px 1px;
        
    }
    .container {
        overflow: visible;
        position:absolute;
        background:#eee;
        border:1px solid black;
        width:200px;
        height:50px;}
    .title {
       position: absolute;
        left:0;
    }
</style>

<body>
<!-- JUST A TIMELINE PLACEHOLDER SO THAT THE VIEW CAN SCROLL -->
<div class='dummy_timeline'></div>

<!-- EVENT 1 -->
<div class='container' style='left:120px; top:40;'>
  <div class='title'>TITLE1</div>
</div>
<!-- EVENT 2 -->
<div class='container' style='left:50px; top:140;'>
  <div class='title'>TITLE2</div>
</div>

</body>
</html>

What I need to happen is this:

(1) When the div is completely in view the title stays in its default position

OUTSIDE THE VIEW  | IN VIEW
                  |  
                  |  [----------------]
                  |  [ TITLE2         ]
                  |  [----------------]
                  | 

(2) When srolling, the title starts moving to the right to stay visible

OUTSIDE THE VIEW  | IN VIEW
                  |   
                  |---------]
                  | TITLE2  ]
                  |---------]
                  |

(3) When srolling even more, the title moves out of its container and stays in view until the container has completely disappeared

OUTSIDE THE VIEW  | IN VIEW
                  |  
                  |-]
                  | ]TITLE2
                  |-]
                  |

| = the left-most side of the browser window

Salman A
  • 262,204
  • 82
  • 430
  • 521
  • If I understood your question it's yes, you can do it by using CSS3 animation `@keyframes`, you have to handle with the div position or div transform whatever you want, and the animation duration – Omar Zaoujal Oct 26 '21 at 12:06
  • [https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport](https://stackoverflow.com/questions/123999/how-can-i-tell-if-a-dom-element-is-visible-in-the-current-viewport) – B001ᛦ Oct 26 '21 at 12:07

1 Answers1

0

Pure CSS

Salman A suggested that I would change the requirements as to not to allow the right edge of the title go past the right edge of its parent. The pure CSS solution, as suggested by Salman A, would be simply to change the CSS for the title element to read:

.title {
  display: inline-block;
  position: sticky;
  left: 0;
}

This may even be the desired behavior so I'm inclined to change my requirements.

JavaScript

For future reference, I'm also enclosing the JavaScript solution I found by following the link (How can I tell if a DOM element is visible in the current viewport?) found in the comment by B001ᛦ, which, in turn, lead me to a post by www139. I adapted the code provided by www139 to check the horizontal positions of elements and, when needed, to adjust the padding of the title to keep it in view. This version allows the title to go past the right edge of its parent. The gist is in the <script> section.

<html>
<style>
  .dummy_timeline {
    width:5000px;
    top:0px;
    left:0px;
    height:20px;
       background: linear-gradient(90deg, #222 1%, transparent 1%) 1px 0, #fff;
       background-size: 200px 1px;
  }
  .container {
    overflow: visible;
    position:absolute;
    background:#eee;
    border:1px solid black;
    width:200px;
    height:50px;}
  .title {
    position: absolute;
    left:0;
  }
</style>

<script>
  window.onscroll = function() {
      var elements = document.getElementsByClassName('container');
      for (var i = 0; i != elements.length; i++) {
          element = elements[i];
          offsetLeft = element.getBoundingClientRect().left;
          offsetRight = element.getBoundingClientRect().right;
          span = element.getElementsByClassName('title')[0];

          if (offsetRight <= 0) {
              span.style.paddingLeft = 0;
          } else if (offsetLeft <= 0) {
              span.style.paddingLeft = -offsetLeft;
          } else {
              span.style.paddingLeft = 0;
          }
      }
  };
</script>
<body>
<!-- JUST A TIMELINE PLACEHOLDER SO THAT THE VIEW CAN SCROLL -->
<div class='dummy_timeline'></div>
<!-- EVENT 1 -->
<div class='container' style='left:120px; top:40;'>
  <span class='title'>TITLE1</span>
</div>
<!-- EVENT 2 -->
<div class='container' style='left:50px; top:140;'>
  <span class='title'>TITLE2</span>
</div>
</body>
</html>