WebアプリでLINEトーク風のUIをつくる肝となるCSSプロパティ「flex-direction: column-reverse」
Web制作では、上から下にコンテンツを並べていくのが定石です。スクロール位置も初期位置は上部ですので、FacebookやXのフィードのように、「最新投稿から下に遡って読んでいく」メッセージUIは、実現しやすく、開発もさほど難しくありません。
しかしながら、InstagramやLINE、Xのメッセージのように「下から上に読み進めていく」UIは、Web制作の常識から外れます。
- 表示した時の初期位置は最下部
- 新規投稿は最下部に追加される
- 上に遡ると、過去の投稿がみることができる
長らく、私がつくったアプリでも、このUIパターンは鬼門でした。何とかそれっぽく見せるために
- 全部表示して上部からのスクロール量を計算(この段階では
opacity: 0
) - 最下部にJSでスクロール
- スクロールが完了したら
opacity: 100
に
と疑似的に「初期位置を最下部にみせる」ようにしたり、スクロール量が一定以下になったら無限スクロールを再現するために
- 無限スクロール前のスクロール量を保存
- 過去のコンテンツが表示されたら高さを計算
- 過去のコンテンツの高さ + 無限スクロール前のスクロール量だけスクロール
をしたり、今おもっても結構健気な実装をしていました。「Webは上から下にスクロールするものだから仕方ない」と。ただ、今年に入ってからとてもすばらしいCSSに出会って、これを覆せたので共有します。
flex-direction: column-reverse;
救世主 いや、本当救世主。MDNをみたところ、早いブラウザでは10年前には実装。最も遅いFireFoxでも2020年9月にはサポートしているので、もっとはやく知りたかった。とても簡単にいうと、Flexboxのプロパティのひとつで、縦に並んでいるFlexboxの順序を逆転します。
そして、 初期値位置も逆転します。
codesandboxで、この挙動についてとてもわかりやすいサンプルデモがあったのでこちらをご覧ください。
.scrollTop
も逆転するので、最下部にスクロールしている時はスクロール量がゼロ。上に上がるにつれて、スクロール量が肥大化します。もちろんのこと、上部にコンテンツを追加しても、スクロール位置はかわりません。最高。
当然Flexbox内の挙動だけを制御するので、スクロールコンテンツ内を大きなFlexboxで覆う制約はありますが、これを使えば、Instagramメッセージ風UIを簡単に実装できます。
以下のデモは、Ionic Angularを用いたものです。Indexが逆転されて、下から上にスクロールできることがわかりますね。
flex-direction: column-reverse;
の使い方
これだけ。簡単、最高。
div.reverse-items {
width: 100%;
height: 100%;
display: flex;
flex-direction: column-reverse;
}
まとめ
InstagramやLINE、Xのメッセージのように「下から上に読み進めていく」UIは、Web制作の常識から外れますが、flex-direction: column-reverse;
を使えば、簡単に実装できます。これを使って、WebアプリのUIをより自由につくってもらえればと思います。 とはいえ、私だけが知るのが遅かっただけで実は有名なやり方だったりするかもしれませんw
それでは、また。
Discussion