CSSでLINE風のふきだしを出来るだけシンプルに作ってみる
雑記ブログなので、それほどコメントやメールは頂かないのですが、最近「CSSで画像の好きな位置を円形にトリミングする方法」と「JavaScriptで1文字ずつ表示するサンプルをドラクエ風に作ってみる」という、いずれも1年ほど前に投稿した記事についてコメントや質問を頂きました。
その合せ技………というほどのものではないのですがw
LINE風のふきだし画面をCSSで作ってみようかなぁーと思い立って作ってみました。
CSSで作ったLINE風のふきだし画面サンプル
こちらは左側に表示される吹き出しのメッセージです。
二行目はこんな感じ。
こちらは右側に表示される吹き出しのメッセージです。
二行目はこんな感じ。
三行目はこんな感じ。
LINE風とか言いつつ、実はぼくLINEをやってないので本当にこんな感じなのかよく知らないんですけどね…。でもほら、なんかこういう感じのふきだしで記事を書いているブログとかちょいちょい見かけるじゃないですか。
例えば、先生と生徒に分かれて会話形式で解説する記事なんかで使われること多いですよね。
ぼくもそういうデザインを使ったことはあるのですが、CSSをまるパク…ごほん…参考にして貼り付けていただけなので、ちょっとタグが多いなぁ…と気になっていました。
そこで、せっかくなので思いつく限り、シンプルなHTMLで済むようにしてみました。
CSSで作ったLINE風のふきだし画面のHTMLタグ部分
はい、こんだけです。
<div class="talk">
<div class="talk_left">
<p>こちらは左側に表示される吹き出しのメッセージです。<br>二行目はこんな感じ。</p>
</div>
<div class="talk_right">
<p>こちらは右側に表示される吹き出しのメッセージです。<br>二行目はこんな感じ。<br>三行目はこんな感じ。</p>
</div>
</div>
よくサンプルとして公開されているコードだとタグがかなり多く、全体枠はもちろん、丸アイコンの部分、矢印の部分、吹き出しの部分でタグが分かれているケースもあり、量が増えるとちょっと見づらいなぁ…と感じていました。
なので、全体枠は talk クラスのみ。左ふきだしは div.talk_left と中のテキストとなる p タグのみ。
アイコン指定のimgタグすらありません。…………さすがにimgタグは付けても良かったかな、と完成してから思いましたけどw
LINE風ふきだし画面のCSS部分
HTMLをシンプルにした分、CSSは少々長いかも知れません。
/* 全体の枠 */
.talk {
background-color:rgb(113,147,193); /* LINEっぽい背景色 */
padding:1em;
overflow:auto;
}
/* 左のトークボックス */
.talk .talk_left:before { /* 左の丸アイコン */
content:'';
display:inline-block;
width:50px;
height:50px;
vertical-align:top;
border-radius:50%;
background-size:cover;
background-image:url(icon_left.jpg); /* ←アイコンはここを変更 */
}
.talk .talk_left p:before { /* 左ふきだしの左三角を描画 */
content: '';
position:absolute;
top:8px;
left:-20px;
border: 12px solid transparent;
border-right:12px solid white;
}
.talk .talk_left p { /* 左ふきだしの本体 */
display:inline-block;
position:relative;
background-color:white;
border-radius:10px;
padding:10px;
margin:0 0 0 10px;
}
/* 右のトークボックス */
.talk .talk_right:after { /* 右の丸アイコン */
content:'';
display:inline-block;
width:50px;
height:50px;
vertical-align:top;
border-radius:50%;
background-size:cover;
background-position:-10px;
background-image:url(icon_right.jpg); /* ←アイコンはここを変更 */
}
.talk .talk_right {
float:right; /* 右のふきだしは全体的に右寄せ */
margin-top:1em;
}
.talk .talk_right p:after { /* 右ふきだしの右三角を描画 */
content: '';
position:absolute;
top:8px;
right:-20px;
border: 12px solid transparent;
border-left:12px solid #85e249;
}
.talk .talk_right p { /* 右ふきだしの本体 */
display:inline-block;
position:relative;
background-color:#85e249;
border-radius:10px;
padding:10px;
margin:0 10px 0 0;
}
とはいえ、.talkはただの全体枠ですし、ふきだしも
- .talk_left:before
→丸アイコンの描画用 - p:before
→ふきだしの矢印(尻尾)の描画用 - p
→ふきだし本体
という3つで構成されているに過ぎません。
左と右で3つずつ使うので、合計6個の要素になってますけど、やってることは変わりません。
ポイントとしては丸アイコンの描画には疑似要素の :before 内で background-image を使いつつも、content:''; と display:inline-block; を指定することで、画像のサイズ指定(width/height)が出来るように小細工しているあたりでしょうか。
ここはこんな小難しくせずとも、imgタグで丸アイコンを描いたほうが良かったかなぁ…と思わなくもありません。HTMLタグをシンプルにしようと、ちょっと無理し過ぎた感も。
それから、ふきだしの矢印(あるいは尻尾?)部分についてはCSSで三角形を描くときにはもはやおなじみとなった transparent の指定です。
transparentで三角形が出来る理由
「css transparent 三角形」などでググれば解説しているページが沢山出てくると思いますが、実際にご自分で10pxくらいの太い色違いの枠線を描いてみるとわかりやすいかと思います。
例えば、下記のように10pxの大きさのdivを10pxのそれぞれ異なった色のborderで囲ってみるとこうなります。
<div class="test"></div>
<style>
div.test {
width:10px;
height:10px;
border-top:10px solid red;
border-right:10px solid green;
border-bottom:10px solid blue;
border-left:10px solid black;
}
</style>
ボーダーの角が斜めに接続されているのがわかりますよね?
では、divのサイズを0にするとどうなるのか。
当然、真ん中の白い部分がなくなるため、ボーダーの三角部分だけが残ります。
じゃあ、あとは残したい三角形だけそのままにして、残りを transparent (=透明)にしてしまえば三角形の完成、というわけです。
<div class="test3"></div>
<style>
div.test3 {
width:0px;
height:0px;
border-top:10px solid red;
border-right:10px solid transparent;
border-bottom:10px solid transparent;
border-left:10px solid transparent;
}
</style>
この例ではborder-topだけ色付きにしたので、下三角が出来ました。
こうした仕組みを使って、ふきだしの矢印(尻尾)を作っています。
まとめ
- 思いつきでLINE風のふきだし画面をCSSで作ってみた。
- HTMLタグ部分をシンプルにするため、CSS側で丸アイコンなども表示するようにした。
- 疑似要素(before)の中で画像をリサイズするためにはcontent:''とinline-blockの指定が必要。
- ふきだしの矢印(尻尾)を作るにはborderのtransparentを使うと楽。
複雑(?)なところはこんなところでしょうか。
あぁ、あと複雑かどうかはわかりませんが、ややわかりにくい部分として、float:leftとfloat:rightがありましたね。floatを付けると要素を左右に寄せられるので便利なのですが、高さが無くなります。
CSS初心者が一番ハマりやすい部分だと思うのですが、floatで高さが0になると、その親要素の高さも変わらなくなるんですよね。
先述の例で言うと .talk の部分です。
CSSを見てもらえればわかりますが、.talkの中でわざわざoverflow:auto;を指定しているのは、子要素がfloatでも高さを計算してくれるようにするためです。
このことを覚えておくだけでもCSSでのレイアウトが格段に楽になるかと思います。