CSSだけで吹き出しデザインの尖っている部分をうまい具合に作りたい!!

こんにちは、ユアサです。
吹き出し付きのコメントがあるようなページのコーディングをすることがありますが、その度に格闘していた『吹き出しの尖っている部分どう作るか問題』に(一旦)終止符を打ちたいので、今回は備忘録も兼ねて自分が考えた方法について書きたいと思います。

(吹き出しの尖っている部分ですが「ツノ」や「しっぽ」と呼ばれているらしいので、以下その呼び方で書いていきます)

調べるとよく出てくる作成方法

テキストの要素を親要素とし、擬似要素で三角形を作ってpositionプロパティで位置調整をしています。吹き出しが背景色のみなら擬似要素1つ、枠線があるものの場合は擬似要素を2つ用意して重ねることで枠線があるように見せる・・・というやり方が一般的かと思います。

See the Pen comnent01 by felly (@felly00505) on CodePen.

今回この記事でお話ししていきたいのが、後者の枠線ありの吹き出しです。上記のコードで実装していますが、しっぽの辺りに拡大してみるとうっすらと黒い線が表示されていることが確認できるかと思います。

これの正体は擬似要素たちの親要素にあたるテキストの要素に付与されたborderプロパティで、ブラウザによってはこの黒い線がくっきり表示されてしまっている場合もあります。
原因は不明ですが、おそらく擬似要素after(白い三角形)の座標とテキスト要素の枠線が端数で僅かにずれ、隙間ができてしまってこの現象になってしまっているのかもしれません。

ちなみに、三角形をCSSで作成する以前にSVGで吹き出しのしっぽを作成する方法もありますが、上記と同様の問題があるので難しいかと思います。

普通にページを閲覧している分には気づきませんが、少しでも拡大すると表示されてしまうのでどうにかしたいですね。

隙間をどうにかして埋めたい

端数が出てしまって隙間ができるなら、擬似要素after(白い三角形)を少しずらせばいいじゃないか!と最初に考えて実装してみました。

See the Pen comment01 by felly (@felly00505) on CodePen.

擬似要素afterを可視化しやすいように赤色にしてみました。右側に少しずらすことによって枠線との隙間を無くし、黒い線が表示されないことが分かります。

問題解決!といきたいところですが、このやり方はあまり好ましくはありません。枠内にパディングが効いているので今回のようなケースはおそらく不具合はないかもしれませんが、これがもし枠線とテキストとの間隔が狭かった場合に擬似要素afterとテキストが被ってしまうことが予想されます。

そこで少し視点を変えて、作り方を変えてみることにしました。

See the Pen comment02_fix01 by felly (@felly00505) on CodePen.

テキスト要素はそのままで、擬似要素before・afterの役割を変えて作成しました。
擬似要素beforeは今まで枠線用の三角形として作成していましたが、これを「黒枠・白背景の四角形」とし、擬似要素afterはテキスト要素の枠内と繋げるための白い三角形だったのを「beforeを隠すための白背景」として作成することにしました。

擬似要素beforeが吹き出しのしっぽになるので、それっぽく見えるようにtransform: rotate(-45deg) skew(30deg, 30deg)で角度を調節して菱形に見えるようにします。擬似要素afterを親要素のテキスト要素のサイズいっぱいに広げて白背景にします。

ただ作っただけではまだ吹き出しには見えないので、最後に重ね順を変更します。親要素であるテキスト要素をz-index: 0;、擬似要素beforeをz-index: -2;、擬似要素afterをz-index: -1;と指定することによって重ね順を上からテキスト要素→擬似要素after→擬似要素beforeとし、『テキスト要素を最前面に持ってきつつ、その下にしっぽ用の四角形を敷く。四角形の余分な箇所は白背景で隠す』仕様にしました。

三角形で事足りるはずなのになぜ四角形にしたのか?

確かに吹き出しのしっぽの形状を作るには大きめの三角形を作成し、座標をずらして調整してサイズ感を整えればいいのですが、答えは単純でborder-radiusで角丸が作成できるからです。吹き出しのしっぽの先端部分に当たるborder-radiusに数値を指定して、角丸の吹き出しを再現できます。

また左右交互に向きが変わる会話形式のデザインの場合、beforeのX値だけを変更すれば良いという点もあります。

See the Pen comment02_fix02 by felly (@felly00505) on CodePen.

三角形で作成するよりも汎用性が高そうなので重宝するかな〜?と思っています。もっといい方法があるかもしれませんが。

まとめ

吹き出しの作り方について、自分なりの工夫の過程と方法を書きまとめました。
割と使える方法だと思うので、よければ試してみてください。