あまり自分で使うこともないのですが、cssで作る吹き出し会話について考えてみました。
この手のcssは、はてなブログでもよく取り上げられていて、誰かのをコピペしているようです。そういう系の記事を見かけることはよくあるのですが、中身までしっかり読んでないので具体的にはよくわかってません。なので、まぁ自分で作ってみようと、そういうわけです。
基本の形
基本は右や左にアイコンがあって、その隣に吹き出しがあるというもの。交互になってるのもポイントですね。ということは…
<div class="fuki-box"> <img src="画像URL" /> <div class="fuki">セリフ内容</div> </div>
こんな感じかな?
セリフ部分のスタイル
セリフ部分はdivにボーダーなり付けて角丸にして調整。問題はツノ部分。これはたぶんボーダーで作ってるんだろうな。これ、わたしあまり理解してないんだよな…。
borderでツノ
試しに。
<div style="width:50%;border:10px solid #999;">Test</div>
ふむ。
<div style="width:50%;border:10px solid;border-top-color:#999;border-right-color:#f90;border-bottom-color:#f0f;border-left-color:#9f9;">Test</div>
うんうん。
<div style="width:40px;border:20px solid;border-top-color:#999;border-right-color:#f90;border-bottom-color:#f0f;border-left-color:#9f9;"></div>
ほうほう。
<div style="width:40px;border-top:10px solid #999;border-right:40px solid #f90;border-bottom:30px solid #f0f;"></div>
なるほどね。
<div style="width:40px;border:20px solid transparent;border-right-color:#f90;"></div>
本体とくっつけてみる
<div class="fuki1">これはテスト。</div>
.fuki1{background:#ccc;padding:1em;margin:0 0 0 15px;border-radius:6px;position:relative;} .fuki1::before{content:'';position:absolute;top:calc(50% - 10px);left:-16px;font-size:0;border-top:10px solid transparent;border-right:16px solid #f90;border-bottom:10px solid transparent;}
単色塗りつぶしなら、これで色を揃えればOKなんでしょうな。
ボーダーを付けてみる
ツノはセリフ本文のdivの::beforeで作成して付けるとたぶんいい感じ。で、そのまま本体にボーダーをつけると…
まぁこうなるわな。なので、ツノ部分に白抜きを与えるために、少し位置をずらしたもう1個のツノを::afterで作ってかぶせる。
被せたのを白にすれば…
疑似ボーダーのできあがり。
<div class="fuki4">これはテスト。</div>
.fuki4{padding:1em;margin:0 0 0 15px;border:3px solid #333;border-radius:6px;position:relative;} .fuki4::before{content:'';position:absolute;top:calc(50% - 10px);left:-16px;font-size:0;border-top:10px solid transparent;border-right:16px solid #333;border-bottom:10px solid transparent;} .fuki4::after{content:'';position:absolute;top:calc(50% - 10px);left:-12px;font-size:0;border-top:10px solid transparent;border-right:16px solid #fff;border-bottom:10px solid transparent;}
画像と並べる
喋っている人を表すアイコン画像と並べる方法は、まぁいろいろあるのですが、最近はflexboxが好きなのでこれで。

<div class="fuki-box5"> <div class="fukimg5"><img src="https://cdn1.www.st-hatena.com/users/c-/c-miya/profile.gif" /></div> <div class="fuki5">意識高すぎワロタ。</div> </div>
.fuki-box5{display:-webkit-flex;display:flex;} .fukimg5{width:64px;height:auto;-webkit-flex-shrink:0;flex-shrink:0;} .fuki5{padding:1em;margin:0 0 0 15px;border:3px solid #333;border-radius:6px;position:relative;} .fuki5::before{content:'';position:absolute;top:calc(50% - 10px);left:-16px;font-size:0;border-top:10px solid transparent;border-right:16px solid #333;border-bottom:10px solid transparent;} .fuki5::after{content:'';position:absolute;top:calc(50% - 10px);left:-12px;font-size:0;border-top:10px solid transparent;border-right:16px solid #fff;border-bottom:10px solid transparent;}
ただ、このままだとセリフの量が多くなるとツノの位置が合わなくなる。

ツノの位置をセリフ本文の縦中央にしていたけど、画像に合わせたほうが良いか…?

左右に分けて会話形式に
左右に分けると起こることは「アイコン画像が右になる」「ツノの位置も逆になる」ということ。
- 会話全体をdivで囲んで、その中の奇数と偶数でcssを切り替える
- それぞれ別のクラス名をつける
1.のほうがなんとなく記述量が少なくなる気がしないでもない。ただ必ず左に画像がある方から話し始めなければならなくなりそう。それは面倒そうなので2.を採用。


flexbox使うと並びの方向を変えるだけで済むのがめっちゃ楽。ツノ部分は単に回転させても良かったかも。
まとめ
んー…、まぁこんなものですか。よく使われているのをみると、吹き出しにシャドウつけたりアイコンを丸にしてるのも見かけますが、あまり好みではないのでやらない。
最終的なhtmlとcssは以下の通り。
<div class="fuki-box"> <!-- 左アイコン --> <div class="fuki fukiL"> <div class="fukimg"><img src="画像URL-1" /></div> <div class="fukitxt">テキスト1</div> </div> <!-- 右アイコン --> <div class="fuki fukiR"> <div class="fukimg"><img src="画像URL-2" /></div> <div class="fukitxt">テキスト2</div> </div> </div>
.fuki{ display: -webkit-flex; display: flex; margin: 0 0 1.5em 0; } .fukiR{ -webkit-flex-direction: row-reverse; flex-direction: row-reverse; } .fukimg{ width: 64px; height: auto; -webkit-flex-shrink: 0; flex-shrink: 0; } .fukitxt{ padding: 1em; border: 3px solid #333; border-radius: 6px; position: relative; } .fukiL .fukitxt{ margin: 0 0 0 15px; } .fukiR .fukitxt{ margin: 0 15px 0; } .fukitxt::before,.fukitxt::after{ content: ''; position: absolute; top: 19px; font-size: 0; border-top: 10px solid transparent; border-bottom: 10px solid transparent; } .fukiL .fukitxt::before{ left: -16px; border-right: 16px solid #333; } .fukiL .fukitxt::after{ left: -12px; border-right: 16px solid #fff; } .fukiR .fukitxt::before{ right: -16px; border-left: 16px solid #333; } .fukiR .fukitxt::after{ right: -12px; border-left: 16px solid #fff; }
もっと記述を少なくするだとかスマートにするだとか、いろいろありそうですが、まぁ練習的なものなのでこんなところで。個人的にはボーダーではなくベタ塗りにするのも好きなんですけどね。
