🦀

[CSS組版]SNSアプリの会話っぽい表現の実現例

2024/12/12に公開

CSS組版アドベントカレンダー2024の12日目の記事です。もう記事内容入れ換えられる日がなくなってきた。もう?!

https://adventar.org/calendars/10448

会話ボックス

SNSアプリの会話っぽい表現、つまり会話ボックスみたいなやつです。逆に会話ボックスで通じる方が少ない気もする。

  • 話者のアイコン(ラベル)が主内容(ボディ)の横に付く
    • 話者によってアイコンの位置を左右(上下)入れ換える
  • 主内容は話者方向の区別がつく装飾になっている
  • 主内容はページ分割される可能性がある
  • アイコンと主内容のブロック進行方向の始点または終点位置は統一されている

ラベル位置

で、何が焦点かというとラベル位置の実現方法ですね。::before::afterはHTMLとは離れて指定できるため、.right::before.left::afterのようにすればCSS側だけで実現できるんですが、
セマンティクス的には「話者が違うこと」による::before::afterの使い分けってモヤモヤするわけで。

CSS FlexibleBoxのflex-direction: row-reverseの使いどきは、今!

*-reverse系統はコンテンツの記述順とは別の順序を与えられる! ということでFlexible Boxです。CSS Gridが何故ダメかというと、会話ボックスの場合コンテンツがページを跨ぐ可能性があるからですね。複数の記事で同じこと書いてますが、繰り返し言っておかないとダメなポイントです。

 :root {
                font-family: 'LINE Seed JP_OTF';
            }
            .talk {
                margin:0pt;
                width: 70%;
                background-color:darkcyan;
            }
            .talk > li {
                display: flex;
                margin: 0.5em;
                align-items : start
            }
            .talk > li > p {
                margin: 1em;
                margin-top:0pt;
                padding:0.5em;
                border-radius: 5pt;
            }
            .talk > li.me {
                flex-direction: row;
            }
            .talk >li.you {
                flex-direction: row-reverse;
            }

            .talk >li.me > p {
                background-color:aquamarine;
                border-top-left-radius: 0pt;
            }
            .talk >li.you > p {
                background-color: darkseagreen;
                border-top-right-radius: 0pt;
            }

            li.me::before {
                content: url(../label.jpg);
                width:1.5cm;
                border-radius: 50%;;
            }
            li.you::before{
                content: url(../label.jpg);
                width:1.5cm;
                border-radius: 50%;;
            }
<ul class="talk">
  <li class="me"><p>こんにちは。人間です。</p></li>
  <li class="you"><p>こんにちは。地球です。</p></li>
  <li  class="me"><p><span style="font-style:italic;" lang="en">Oh yeah... Welcome to TSUKUBA University...</span> 🤗</p></li>
  <li class="you"><p style="font-size: larger;">...</p></li>
  <li  class="me"><p>🦀</p></li>
</ul>
  • 話者のアイコン(ラベル)が主内容(ボディ)の横に付く
    • 話者によってアイコンの位置を左右(上下)入れ換える

display:flexflex-directionrowrow-reverseで実現しています。

  • 主内容は話者方向の区別がつく装飾になっている

border-rediuspの全ての角に指定していますが、それぞれの上端で解除(0pt)しています。

  • 主内容はページ分割される可能性がある

Flexの内容はページ分割可能です。ただしラベルを再表示したいとなると難しいでしょう。

  • アイコンと主内容のブロック進行方向の始点または終点位置は統一されている

align-items: startで上端に寄せています。::before ::afterではなくCSS Flexible Boxを使うもう1つの利点です。

組版・ドキュメンテーション勉強会

Discussion