CSSで六角形を表現する

ダークナイトが面白過ぎました。Kameです。

最近某案件にてCSSのみで六角形のパーツを作れないかということで挑戦してみました。
※とりあえずwebkitブラウザのみで考えています。

transform:rotate(); を利用する方法

六角形にする要素の:beforeと:afterを四角形にしてtransform:rotate();してやれば簡単に六角形が作れます。

.square{
	position:relative;
	height:64px;
	background:#09F;
}
.square:before{
	content:"";
	display:block;
	position:absolute;
	top:10px;
	left:-23px;
	width:45px;
	height:45px;
	background:#09F;
	-webkit-transform:rotate(45deg); /* 正方形を45度回転 */
}
.square:after{
	content:"";
	display:block;
	position:absolute;
	top:10px;
	right:-23px;
	width:45px;
	height:45px;
	background:#09F;
	-webkit-transform:rotate(45deg); /* 正方形を45度回転 */
}

しかしこれだけでは角が90度のものしか作れません。

borderでうまいことやる方法

ボーダーをうまいこと使えば色んな角度・大きさの三角形を作ることができます。
それを利用して六角形を作成します。

.square{
	position:relative;
	height:64px;
	background:#09F;
}
.square:before{
	content:"";
	display:block;
	position:absolute;
	top:0;
	left:-16px;
	border-top:32px solid transparent; 
	border-bottom:32px solid transparent; /* 上下のborderを透過 */
	border-right:16px solid #09F;
}
.square:after{
	content:"";
	display:block;
	position:absolute;
	top:0;
	right:-16px;
	border-top:32px solid transparent;
	border-bottom:32px solid transparent; /* 上下のborderを透過 */
	border-left:16px solid #09F;
}

borderの幅をうまく調整してやれば色んな角度を持った六角形を作成することができます。

しかしこれでもいくつか・・・
borderなので単色しか表現できないのでグラデーションを入れるなどの凝った六角形を作ることができません。

transform:skew(); を利用してうまいことやる方法

transform:skew(); というプロパティがあったことをすっかり忘れていました。
このプロパティは図形を指定した角度分上下に「傾け」ます。つまり平行四辺形を作ることができます。
こいつと先ほどのrotateを合わせれば角度自由、塗り自由の六角形を作ることができます。

.square{
	position:relative;
	height:64px;
	background: -webkit-gradient(linear, left top, left bottom, from(#abddff),to(#09F));
}
.square:before{
	content:"";
	display:block;
	position:absolute;
	top:11px;
	left:-21px;
	width:42px;
	height:42px;
	background: -webkit-gradient(linear, right top, left bottom, from(#abddff),to(#09F));
	-webkit-transform:rotate(-50deg) skew(-10deg); /* -10度傾けて、-50度回転 */
	 /* 同時に指定する場合は半角スペースを入れる */
}
.square:after{
	content:"";
	display:block;
	position:absolute;
	top:11px;
	right:-21px;
	width:42px;
	height:42px;
	background: -webkit-gradient(linear, right top, left bottom, from(#abddff),to(#09F));
	-webkit-transform:rotate(-50deg) skew(-10deg); /* -10度傾けて、-50度回転 */
	/* 同時に指定する場合は半角スペースを入れる */
}

このようにグラデーションも再現した六角形を作ることができます。
今回はひし形にして上下ぴったりに合わせていますがもっと角度を出したい等の場合は、
要素を更にラップして高さをoverflow:hidden;にし、
かなりうまいこと計算をして合わせれば表現可能だと思います。(未実験)

transformのrotateやskewについてはAndroidもvar1.6からサポートしている(2.1では表示確認済)っぽいので、
スマホ案件であれば安心して使うことができます。

まとめ

CSS3すごいなーとも思いましたが懸念点もいくつかあります。

  • 角度、辺の長さの計算が超面倒(久々に√とかを使った)
  • 計算するとだいたい小数点が発生するので完全にぴったりくっつけるのはほぼ不可能
  • skewすると若干borderがガビる(図参照)

ガビってしまうのは少し痛いかなーと感じました。
しかし今回√の計算にGoogle大先生を利用しましたがホントあの方賢いですね。