<div class="container">
  <p>We want to indicate if there's more to scroll by adding a decreased opacity on the top or bottom element.</p>
  <p>However, if we're at the top, we don't want to decrease the opacity of the first element. And if we're at the bottom, we don't want to decrease the opacity of the last element.</p>
  <p>We'll use <a href="https://caniuse.com/mdn-css_properties_animation-timeline">Scroll Driven Animations</a> for this usecase and <a href="https://caniuse.com/mdn-css_at-rules_property">@property</a>. Chrome only for now. Do not use in production.</p>

  <div class="scroll">
    <p class="message me">Hey!</p>
    <p class="message you">Hey!</p>
    <p class="message me">What's up?</p>
    <p class="message you">All good, you?</p>
    <p class="message me">All good.</p>
    <p class="message you">Cool.</p>
    <p class="message me">Cool.</p>
    <p class="message you">Cool.</p>
    <p class="message me">Cool.</p>
    <p class="message you">Cool.</p>
    <p class="message me">Cool.</p>
    <p class="message you">Cool.</p>
    <p class="message me">Cool.</p>
    <p class="message you">Cool.</p>
    <p class="message me">Cool.</p>
    <p class="message you">👋</p>
    <p class="message me">👋</p>
  </div>
</div>
@supports (animation-timeline: view()) {
  @keyframes y-distribution {
    0% { opacity: 0.3; }
    25% { opacity: 1 }
    75% { opacity: 1 }
    100% { opacity: 0.3; }
  }

  .message {
    animation: y-distribution ease-in-out reverse both;
    animation-timeline: view();
    animation-range: normal;
  }
}

/* Global styles */
body {
  min-height: 100vh;
  min-height: 100dvh;
  background: #f0f0f0;
  font-family: system-ui, sans-serif;
  padding-top: 1rem;
}

.container {
  max-width: 30rem;
  margin: 0 auto;
}

.scroll {
  max-height: 500px;
  overflow-y: auto;
  margin-top: 3rem;
}

.message {
  padding: 1rem;
  border-radius: 1rem;
}

.message + .message {
  margin-top: 1rem;
}

.message.you {
  margin-right: 2rem;
  background: white;
}

.message.me {
  margin-left: 2rem;
  background: rgb(207 58 0);
  color: white;
  text-align: right;
}


External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.