CSSのみで菱形を作る方法まとめ
菱形を大量に使ったサイトを制作しているんですが、画像を使わずにCSSのみで菱形を作る方法はいくつかあって、それぞれに向き不向きみたいな特徴があるので、作り方も含めて自分用にまとめてみました。
ちなみに「菱形を大量に使ったサイト」は、このサイトのリニューアルでして、今年の9月から作り始めてまだ完成していないという…。
基本となるHTMLとCSSとデモ
以下のHTMLとCSSがベースとなります。たぶん、1つのdiv
で全てできると思いますが、普通はテキストをのせたり、リンクを貼ったりすると思うので、実用面を考えてこの形としました。
HTML
<div class="contents">
<div class="diamond">
<a href="#">
<div class="diamond__inner">
<p>テキスト</p>
</div>
</a>
</div>
</div>
CSS
.contents{
position: relative;
height: 300px;
}
.diamond {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 200px;
height: 200px;
margin: auto;
}
hover時のスタイル等、不要と思われる部分は省略しています。その他の必要な要素は各パートに記載してあります。
デモ
デモは以下のリンクからどうぞ。
border
で菱形をつくる
border
を利用して菱形を作る方法になります。
CSS
.diamond__inner {
width: 0;
height: 0;
border-top: 100px solid transparent;
border-right: 100px solid #3676BD;
border-bottom: 100px solid transparent;
border-left: 0 solid transparent;
}
.diamond__inner:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 100px;
width: 0;
height: 0;
margin: auto 0;
border-top: 100px solid transparent;
border-right: 0 solid transparent;
border-bottom: 100px solid transparent;
border-left: 100px solid #3676BD;
}
.diamond__inner p {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
color: #fff;
z-index: 1;
}
ポイントなど
疑似要素を使い、border
で三角形を2つ作って隣り合わせにしています。
border
の一部をtransparent
で透過させているだけなので、a
要素で囲んだ時、リンク領域は菱形の部分をはみ出して表示されます。
グラデーションで菱形をつくる
background
のlinear-gradient
を利用して菱形を作る方法になります。
CSS
.diamond__inner {
width: 200px;
height: 200px;
background: -webkit-linear-gradient(45deg, transparent 50%, #3676BD 50%), -webkit-linear-gradient(135deg, #3676BD 50%, transparent 50%), -webkit-linear-gradient(45deg, #3676BD 50%, transparent 50%), -webkit-linear-gradient(135deg, transparent 50%, #3676BD 50%);
background: linear-gradient(45deg, transparent 50%, #3676BD 50%), linear-gradient(-45deg, #3676BD 50%, transparent 50%), linear-gradient(45deg, #3676BD 50%, transparent 50%), linear-gradient(-45deg, transparent 50%, #3676BD 50%);
background-position: bottom left, top left, top right, bottom right;
background-size: 100px 100px;
background-repeat: no-repeat;
}
.diamond__inner p {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
color: #fff;
}
ポイントなど
1つのブロック(四角)を4分割して、それぞれグラデーションのdeg値を斜めにし、その半分を透過することで表現しています。理由は分からないですが、この時のdeg値が大きいとシャギーが出る場合があるので、なるべく小さな数値にしたほうがいいようです。
それとは別に、形がややいびつになる場合もあって、ブラウザや環境の問題かもしれませんが、残念ながら理由は分かりませんでした。
グラデーションの場合も、transparent
で透過しているだけなので、a
要素で囲んだ時、リンク領域は菱形の部分をはみ出して表示されます。
また、グラデーションの場合は、transition
プロパティが効かないので、ホバー時のアニメーション効果を付与できないようです。
transform
で菱形をつくる
transform
のrotate
を利用して菱形を作る方法になります。
CSS
.diamond {
left: 0;
right: 0;
width: 141px;
height: 141px;
margin: auto;
background: #3676BD;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
overflow: hidden;
}
.diamond__inner {
position: absolute;
top: -29.5px;
left: -29.5px;
width: 200px;
height: 200px;
line-height: 200px;
color: #fff;
background: transparent;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
ポイントなど
transform:rotate
で正方形を45度回転させ表現しています。子要素も回転してしまうため、テキスト等をのせる時は、子要素を-45度して逆回転させ水平に戻します。
45度回転させると対角線の長さが横幅となりますが、実際のwidth
とheight
の長さは、元の数値が基準となります。そのため、正確に配置したい場合には、対角線の長さ(一辺の長さ×√2)を考慮する必要があります(見た目上は、元の数値から「対角線の長さ – 一辺の長さ」分だけ左右に飛び出す)。※デモでは、200pxの幅に抑えたかったので、対角線を200pxとして、width
およびheight
を141pxの長さに指定しています。
テキストを水平に配置するため-45度で逆回転させているわけですが、テキストを回転させるとブラウザや環境によっては、ホバー時にちらつくことがあります。
transform:rotate
の場合、回転させた要素に対してoverflow:hidden
を指定することで、a
要素で囲んだときにもリンク領域をはみ出さずに表示することができます。
【おまけ】-webkit-box-reflect
で菱形をつくる
webkit系のブラウザのみとなりますが、-webkit-box-reflect
を利用して菱形を作る方法になります。この場合のみ、HTMLが若干変わります。
HTML
<div class="contents">
<div class="diamond">
<a href="#">
<div class="diamond__inner"></div>
</a>
<p>テキスト</p>
</div>
</div>
CSS
.diamond__inner {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-top: 100px solid transparent;
border-left: 0 solid transparent;
border-right: 100px solid #3676BD;
border-bottom: 100px solid transparent;
-webkit-box-reflect: right;
}
.diamond.p {
position: absolute;
top: 50%;
left: 50%;
margin: -10px 0 0 -25px;
color: #fff;
}
ポイントなど
border
で作った三角形を鏡面反射させて表現しています。鏡面反射なので、子要素にテキストがあるとそれらも反転してしまうため、HTMLを少し変えてあります。
非常に不安定で、webkit系のブラウザでもうまく表示されないときがあります。また、ホバー時の挙動も少しおかしいです。
反射させているだけなので、a
要素で囲んだ時、リンク領域は反射面には及ばず、元々の要素部分のみがリンク領域となります。
まとめ
以上、CSSのみで菱形を表現する4つの方法でした。上記のうち、border
とtransform:rotate
が実用的で、それ以外がちょっと使いづらいかなという印象です。
個人的にはtransform:rotate
が一番使い勝手がいいかなと思っています。配置の際にマージンなどの数値を合わせるのが少し大変ですが、リンク領域をはみ出さないでいけるのはこれしかないので、リンクありの時は、これ一択という感じです。
他にもあるのかもしれませんが、気付いたら追加しておきます。