UNORTHODOX WORKBOOK

BLOG TOPWeb DesignCSSのみで菱形を作る方法まとめ

CSSのみで菱形を作る方法まとめ

diamond-in-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時のスタイル等、不要と思われる部分は省略しています。その他の必要な要素は各パートに記載してあります。

デモ

デモは以下のリンクからどうぞ。

DEMO PAGE

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要素で囲んだ時、リンク領域は菱形の部分をはみ出して表示されます。

borderの菱形デモ

グラデーションで菱形をつくる

backgroundlinear-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で菱形をつくる

transformrotateを利用して菱形を作る方法になります。

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度回転させると対角線の長さが横幅となりますが、実際のwidthheightの長さは、元の数値が基準となります。そのため、正確に配置したい場合には、対角線の長さ(一辺の長さ×√2)を考慮する必要があります(見た目上は、元の数値から「対角線の長さ – 一辺の長さ」分だけ左右に飛び出す)。※デモでは、200pxの幅に抑えたかったので、対角線を200pxとして、widthおよびheightを141pxの長さに指定しています。

テキストを水平に配置するため-45度で逆回転させているわけですが、テキストを回転させるとブラウザや環境によっては、ホバー時にちらつくことがあります。

transform:rotateの場合、回転させた要素に対してoverflow:hiddenを指定することで、a要素で囲んだときにもリンク領域をはみ出さずに表示することができます。

transform:rotateの菱形デモ

【おまけ】-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要素で囲んだ時、リンク領域は反射面には及ばず、元々の要素部分のみがリンク領域となります。

-webkit-box-reflectの菱形デモ

まとめ

以上、CSSのみで菱形を表現する4つの方法でした。上記のうち、bordertransform:rotateが実用的で、それ以外がちょっと使いづらいかなという印象です。

個人的にはtransform:rotateが一番使い勝手がいいかなと思っています。配置の際にマージンなどの数値を合わせるのが少し大変ですが、リンク領域をはみ出さないでいけるのはこれしかないので、リンクありの時は、これ一択という感じです。

他にもあるのかもしれませんが、気付いたら追加しておきます。

ABOUT

it's me

長野県北部を拠点にフリーランスとして活動しています。
Webサイトの制作をメインに、グラフィックデザインなどの制作も行っています。 Twitter / GitHub / About

PAGE TOP