枠線付き吹き出しの完成!

ミニブログの隆盛以降ウェブ上でよく見かける吹き出しをCSSで作るお話。単色のものはかなり前に書いた。今回はそれに枠線をつけてみよう! みよう! みよう!

Demo: Bordered Speech Bubble

枠線は単なるsolidborderで少し角を丸めただけ。

尻尾を付ける

:before擬似要素を使う。デモの3番目のサンプルのように、まず枠線と同じ色で三角形を作る。三角形は以前のエントリで書いた手法と同じで、左右のbordertransparentにすることによって作る。

.speech-bubble:before {
  border-top-width: 16px;
  border-right-width: 16px;
  border-bottom-width: 0;
  border-left-width: 16px;
  border-color: #369 transparent;
  border-style: solid;
  display: block;
  position: absolute;
  bottom: -16px;
  left: 16px;
  width: 0;
  height: 0;
  content: "";
}

bottomに負の値を指定して下方向にずらせば下に尻尾がつくようになる。

尻尾の中をくり抜く

:before擬似要素で作った三角と同じものを今度は:after擬似要素で背景色と同じ色で作る。

.speech-bubble:after {
  border-top-width: 16px;
  border-right-width: 16px;
  border-bottom-width: 0;
  border-left-width: 16px;
  border-color: #9cf transparent;
  border-style: solid;
  display: block;
  position: absolute;
  bottom: -10px;
  left: 16px;
  width: 0;
  height: 0;
  content: "";
}

コードはほとんど同じ。内側をくり抜くようにするためbottomで指定する負の値を控えめ(borderWidth - Math.sqrt(Math.pow(borderWidth, 2) * 2))にするだけ。具体的には以下の様な位置に配置する。

尻尾のくり抜き。

わかりやすいように色を変えておいたが、これを背景色と合わせればきれいにくり抜かれることになる。


以上を組み合わせるとポストモダンブラウザ(要出典)では最初に挙げたスクリーンショットのような枠線付き吹き出しが完成する。

おまけ

長いのでSCSSのpartialを作っておいたりすると便利な気がする。

@mixin bordered-speech-bubble($background-color: #9cf, $border-color: #369) {
  border: 4px solid $border-color;
  position: relative;
  background-color: $background-color;
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;

  &:before {
    border-top-width: 16px;
    border-right-width: 16px;
    border-bottom-width: 0;
    border-left-width: 16px;
    border-color: $border-color transparent;
    border-style: solid;
    display: block;
    position: absolute;
    bottom: -16px;
    left: 16px;
    width: 0;
    height: 0;
    content: "";
  }

  &:after {
    border-top-width: 16px;
    border-right-width: 16px;
    border-bottom-width: 0;
    border-left-width: 16px;
    border-color: $background-color transparent;
    border-style: solid;
    display: block;
    position: absolute;
    bottom: -10px;
    left: 16px;
    width: 0;
    height: 0;
    content: "";
  }
}

というミックスインを含んだSCSSファイルを_bordered-speech-bubble.scssという名前で作っておけば、

@import "bordered-speech-bubble";

.speech-buble {
  @include bordered-speech-bubble(#9cf, #369);
}

と書くだけで使える。大抵作っても使わないんですけども!