YOUTRUSTのタイムラインに表示される知り合いかも?一覧のスクロール挙動のちょっとした工夫

こんにちは!YOUTRUSTの春日(YOUTRUST / X)です。

冬真っ只中でとても寒いですね。どうやらカプサイシンという成分を摂取すると体温が上がるらしいです。皆さんも冬はカプサイシンを摂取していきましょう。

さて、今回はYOUTRUSTのPC版に昨年末(2024.12)機能追加されたタイムラインの知り合いかも?一覧表示機能について実装方法とともに紹介します。

実装方法の解説についてはCSSに関する基本的な内容の言及のみで軽く読める内容なので、Web系エンジニアでない方も気楽に読んでいただければと思います!

タイムラインの知り合いかも?一覧表示

YOUTRUSTでは知り合いかも?一覧ページにて自身の知り合い候補を確認することができますが、この度ホーム画面のタイムラインでも表示されるようになりました!

以下の画像のように、タイムラインの1アイテムの中で知り合い候補のカードの一覧が表示されています。

YOUTRUSTのタイムラインに表示される知り合いかも?一覧
知り合いかも?一覧

見切れている部分については横にスクロールすることですべてのカードを確認することができるようになっています。

知り合いかも?一覧スクロール挙動

スクロールの挙動について着目していただきたいのですが、上のアニメーションを見てみるとスクロールした後に必ず2枚のカードが見切れず全体が表示されている位置で止まっていることがわかります。 このような実装を行った意図としては、ユーザーがスクロールした後に止まった位置によってカードが見切れて視認性が悪くならないようにしています。

スクロールを制御した例(見切れずに全体表示されているカードは2枚)

仮にこういったスクロール挙動を制御しないとすると、中途半端な位置でスクロールされてしまって、カード全体がちゃんと表示されているのは1枚だけみたいな状況になってしまうことがあります。

次に、今回のスクロール挙動を実現するための実装方法について説明します。

スクロール挙動を調整するための実装

もし、単純にスクロールした後にカードをビューの中央に配置したいだけであれば、以下のようなCSSを適用することで実現できます。

※今回紹介するコードは全てJSXで書かれています。各要素のCSSにのみ着目してもらいたいため、コンポーネント名の説明は省略します。

<Box // リストを表示する箱
  display="flex"
  flexDirection="row"
  style={{
    overflowX: 'scroll',
    scrollSnapType: 'x mandatory',
  }}
>
  {items.map(item => (
    <ItemCard // リストアイテム
      key={item.id}
      style={{
        scrollSnapAlign: 'center',
      }}
      item={item}
    />
  ))}
</Box>

重要なのはscrollSnapTypescrollSnapAlignです。

scrollSnapTypeは親要素に設定することでスナップ(=スクロール後に該当要素を基準位置として位置調整)する軸や、スナップする際の挙動を設定することができます。

scrollSnapAlignは子要素に設定することでスナップする位置を設定することができます。

※詳しくはMDN Web Docsのスクロールスナップの基本概念をご覧ください。 developer.mozilla.org

ただし、今回はビューの中央にカードが位置するようにしたいのではなく、以下の画像のように2枚のカードの間の余白が中央に位置するようにしたいので少し工夫が必要です。

スクロールを制御した例(見切れずに全体表示されているカードは2枚)

この挙動を実現する方法を2つ、紹介します。

実現方法① 余白部分にだけscrollSnapAlignを設定する

通常、リストアイテム間の余白についてはgapで設定すると思いますが、この余白部分をblock要素として定義してしまって、ここにscrollSnapAlign: 'center'を設定します。 さらに、リストアイテム自体はscrollSnapAlignnoneとすることで、余白要素のみを基準としてスナップするようになります。 このように設定することで、余白部分を中央に位置した状態でスクロールを止めることができます。

※YOUTRUSTでは現在こちらの方法で実装されています。

<Box // リストを表示する箱
  display="flex"
  flexDirection="row"
  style={{
    overflowX: 'scroll',
    scrollSnapType: 'x mandatory',
  }}
>
  {items.map(item => (
    <div key={item.id}>
      <ItemCard // リストアイテム
        key={`item-${item.id}`}
        style={{
          scrollSnapAlign: 'none',
        }}
        item={item}
      />
      <Box // 余白の箱
        key={`spacer-${item.id}`}
        style={{
          scrollSnapAlign: 'center'
        }}
      />
    </div>
  ))}
</Box>

余白部分がビューの中央にくるように位置調整される

実現方法② scrollMarginで位置調整を行う

子要素のscrollMarginを設定することで、スクロール後の位置を調整します。 marginに適切な値を入れることで、①のような余白部分が中央に来るように位置調整することが可能です。

<Box // リストを表示する箱
  display="flex"
  flexDirection="row"
  style={{
    overflowX: 'scroll',
    scrollSnapType: 'x mandatory',
  }}
>
  {items.map(item => (
    <ItemCard // リストアイテム
      key={item.id}
      style={{
        scrollSnapAlign: 'start',
        scrollMarginLeft: '64px',
      }}
      item={item}
    />
  ))}
</Box>

リストアイテムの表示がビューの左端からscrollMarginLeftのぶんだけ右にズレる

これらのように実装することで、スクロール後の停止位置を期待通りに調整することができます!

振り返り

YOUTRUSTのWebアプリを使いやすくするちょっとした工夫の紹介でした!

私自身普段はバックエンドの方を得意としており、バックエンドほどフロントエンド(特にスタイリング)について造詣が深いわけではないため、CSSの挙動をおさらいするいい機会になりました。

最後に

YOUTRUSTではエンジニアを積極的に採用しています!

様々なポジションで求人を出しているので、ご興味のある方は是非以下の募集をご覧ください!

herp.careers