8.08.2012

Pure CSS Speech Balloon

CSS+HTMLのみで吹き出しを作る
ソーシャルボタンの横にあるようなカウンタ吹き出し(「ツイート」とか「いいね!」ボタンの横にあるやつ)を CSS だけで作りたいと思ったけど、IE6 環境でも動作させたい場合は意外な落とし穴があったので備忘録。
<要件>
・二等辺三角形+長方形の形の吹き出しを HTML で出力する
・画像、JavaScript は使わない
・IE6、IE8、Firefox10、HTA(IE6、IE8) で正しく表示されること
・長方形部分の四隅は直角のままでよい(丸めなくてよい)
・吹き出しの輪郭は黒の線になるようにし、その内部は白で塗りつぶす

1. コンテナの作成

まず手始めに、内部の要素を相対座標で指定できるようにするため、描画対象全てを div で囲みこむ。
ここで height を指定しておけば、後々の高さ調整が楽になると思う。
div.balloon {
  position: relative;
  height  : 18px;
}

2. 外側の三角形

偉大なる先人の知恵である border ハックを利用して三角形を描画する。(詳細は記事末尾のリンク先を参照)
外側の黒い三角形を tail1、内側に少しずらした白い三角形を tail2 とする。

綺麗な三角形になるように、font-size と line-height を 0 で指定しておくのがポイント。
:before/:after 擬似要素はIE8 以降しか動作しないため、使用しない。
div.balloon .tail1, .tail2 {
  position    : absolute;
  top         : 4px;
  height      : 0px;
  width       : 0px;
  border      : 5px solid transparent;
  border-left : none;
  border-right: 9px solid #333333;
  font-size   : 0px;
  line-height : 0px;
}
div.balloon .tail1 {
  border-right-color: #333333;
}
しかし、IE6 では早くもここで問題が発生。
border: transparent による透明化処理が行われず、color の色で上・左・下の部分が描画されてしまった。
さらに、border-left: none も無効化されてしまったようである。
ネットで検索してみた結果、これは IE6 の CSS 解釈に不具合があるためらしい。
苦肉の策だが、div 内部で使わないような色(ここでは pink)を指定し、chroma フィルターで透明化することで対応した。また、border-top、border-bottom を個別に指定したら border-left: none が反映されるようになった。
div.balloon .tail_ie6 {
  border-top   : 5px solid pink;
  border-bottom: 5px solid pink;
  filter       : chroma(color=pink);
}
・表示例

 

3. 吹き出し本体

吹き出し本体は、単純な div の設定でよい。ただし、位置取りやフォントサイズは微調整が必要。
div.balloon .body {
  position        : absolute;
  left            : 8px;
  border          : 1px solid #333333;
  background-color: #ffffff;
  color           : #333333;
  font-family     : "Century Gothic";
  font-size       : 11px;
}
・表示例
 0123456789 

 

4. 内側の三角形で縁取り

外側の三角形と同じサイズで色を変えたものを、2ピクセル右にずらして描画する。
尚、z-order を指定すれば、必ずしもこの順番で配置しなくてもよいはず。
div.balloon .tail2 {
  left              : 2px;
  border-right-color: #ffffff;
}
・表示例
 0123456789 

 

5. 全体のコード

<html>
<head>
<style type="text/css"><!--
div.balloon {
  position: relative;
  height  : 18px;
}
div.balloon .body {
  position        : absolute;
  left            : 8px;
  border          : 1px solid #333333;
  background-color: #ffffff;
  color           : #333333;
  font-family     : "Century Gothic";
  font-size       : 11px;
}
div.balloon .tail1, .tail2 {
  position    : absolute;
  top         : 4px;
  left        : 0px;
  height      : 0px;
  width       : 0px;
  border      : 5px solid transparent;
  border-left : none;
  border-right: 9px solid #333333;
  font-size   : 0px;
  line-height : 0px;
}
div.balloon .tail1 {
  border-right-color: #333333;
}
div.balloon .tail2 {
  left              : 2px;
  border-right-color: #ffffff;
}
div.balloon .tail_ie6 {
  border-top   : 5px solid pink;
  border-bottom: 5px solid pink;
  filter       : chroma(color=pink);
}
--></style>
</head>
<body>
<div class="balloon">
  <div class="tail1"></div>
  <div class="body">&nbsp;0123456789&nbsp;</div>
  <div class="tail2"></div>
</div>

<!-- For IE6
<div class="balloon">
  <div class="tail1 tail_ie6"></div>
  <div class="body">&nbsp;0123456789&nbsp;</div>
  <div class="tail2 tail_ie6"></div>
</div>
-->
</body>
</html>

 

参考:
http://www.howtocreate.co.uk/tutorials/css/slopes
http://log.noiretaya.com/164
IE6の対応について
http://stackoverflow.com/questions/5714356/ie6-issue-border-colortransparent-not-working

0 件のコメント:

コメントを投稿