Search code examples
csscss-selectorscss-gradients

Scrollable gradient chat bubbles


I want a white container with chat bubbles masked to a gradient that when scrolled will change with the gradient below, as seen in this example:

Desired UI

I've tried making the part of .container that is behind any chatBubble transparent so that the background of .root is visible.

.root {
  background-color: linear-gradient(red, yellow);
  width: 100vw;
  height: 100vh;
}

.container {
  width: 100%;
  height: 100vh;
  background-color: white
}

.chatBubble {
  background-color: transparent;
  border-radius: 4px;
  min-width: 50;
  padding: 10px;
}
<div class="root">
  <div class="container">
    <chatBubble>This is a chat bubble</chatBubble>
    <chatBubble>This is another chat bubble</chatBubble>
  </div>
</div>


Solution

  • You can "drop shadows" from .bubble:

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    .container {
      --gap: 20px;
      --width: 800px;
      --background: #fff;
      display: flex;
      flex-direction: column;
      max-width: var(--width);
      margin: 16px auto;
      padding: 0 16px;
      overflow: hidden;
      gap: var(--gap);
      box-shadow: 0 0 0 100vw var(--background);
      font-family: sans-serif;
    }
    
    .container:before {
      content: '';
      inset: 0;
      position: fixed;
      z-index: -1;
      background: linear-gradient(purple, blue);
    }
    
    .bubble {
      max-width: 80%;
      background-color: lightgray;
      border-radius: 16px;
      padding: 8px 16px;
      box-shadow: 0 0 0 var(--gap) var(--background);
      position: relative;
    }
    
    .bubble::before,
    .bubble::after {
      content: '';
      position: absolute;
      inset: calc(var(--gap) / -2) auto;
      background-color: var(--background);
      width: var(--width);
    }
    
    .bubble::before {
      right: 100%;
    }
    
    .bubble::after {
      left: 100%;
    }
    
    .bubble.primary {
      background-color: transparent;
      color: #fff;
      align-self: flex-end;
    }
    <div class="container">
      <div class="bubble">show weekend?</div>
      <div class="bubble primary">I'm down!</div>
      <div class="bubble">lets do this its been way to long since we were all together!</div>
      <div class="bubble primary ">Whos down for a pregame</div>
      <div class="bubble">YES! I got the day off! Say when and where?</div>
      <div class="bubble primary">Hows about Old Town at 4? we can get some grub and then head over to the venue</div>
      <div class="bubble">Yeah getting the band back together</div>
      <div class="bubble">show weekend?</div>
      <div class="bubble primary">I'm down!</div>
      <div class="bubble">lets do this its been way to long since we were all together!</div>
      <div class="bubble primary ">Whos down for a pregame</div>
      <div class="bubble">YES! I got the day off! Say when and where?</div>
      <div class="bubble primary">Hows about Old Town at 4? we can get some grub and then head over to the venue</div>
      <div class="bubble">Yeah getting the band back together</div>
      <div class="bubble">show weekend?</div>
      <div class="bubble primary">I'm down!</div>
      <div class="bubble">lets do this its been way to long since we were all together!</div>
      <div class="bubble primary ">Whos down for a pregame</div>
      <div class="bubble">YES! I got the day off! Say when and where?</div>
      <div class="bubble primary">Hows about Old Town at 4? we can get some grub and then head over to the venue</div>
      <div class="bubble">Yeah getting the band back together</div>
    </div>