mask-imageを使って要素の上部を徐々に透過させる

2 min read読了の目安(約2000字

概要

  • 背景が動画で、それの上にチャットのような感じで文字を重ねるというレイアウトがあった
  • チャットはスクロールできるが、上の方のチャットアイテムは徐々に透過して消えていくような見た目にしたい
  • 今回はmask-imageというのがあったので、それを使うことにした
  • 例では背景は画像にしてます
  • ※画像参照先はLorem Picsum

動作確認

https://runstant.com/supermuscles/projects/1e93006e

コード

index.html
index.html
  <body>
    <div class="container">
      <img class='image' src="https://picsum.photos/500/300" alt="" />
      <div class="scroll-container">
        <div class='item'>
          hoge
        </div>
        <div class='item'>
          fuga
        </div>
        <div class='item'>
          piyo
        </div>
        <div class='item'>
          foo
        </div>
        <div class='item'>
          bar
        </div>
        <div class='item'>
          baz
        </div>
        <div class='item'>
          aaa
        </div>
        <div class='item'>
          bbb
        </div>
        <div class='item'>
          ccc
        </div>
      </div>
    </div>
  </body>

main.css
main.css
.container {
  overflow: hidden;
  position: relative;
  height: 300px;
  width: 500px;
}

.image {
  object-fit: cover;
  height: 100%;
  width: 100%;
}

.scroll-container {
  overflow-y: scroll;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  mask-image: linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 80%, transparent);
  -webkit-mask-image: -webkit-linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 80%, transparent);
  padding-top: 32px;
}

.item {
  padding: 8px;
  margin-bottom: 8px;
  color: red;
}

解説

mask-image

  • 背景を透過するのにCSSのmask-imageを使用
  • 何も指定をしないと黒い画像レイヤーとして要素の上に重なるらしい
  • 今回は-webkit-mask-image: -webkit-linear-gradient(90deg, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 80%, transparent);を指定
  • 垂直方向にグラデーションをかけ、上部20%くらいから背景画像に透過するようなマスクをかける

まとめ

  • 背景がただの単色であればabsoluteでグラデーションをかけた要素を上に重ねても実現できるが、その場合はpointer-eventも操作しないといけない
  • 普通にこれの方が良いかも
  • ただし、現状chromeやsafariなどはprefixedしか対応していないので、-webkit-mask-imageがマストになると思われる