【CSS】borderを使って、三角形作るのはやめませんか？

## はじめに
みなさんは、CSSで三角形をつくる時どのように作っていますか？
borderを使って作っていませんか？

この記事では、CSSで三角形をつくるベストプラクティスを紹介します。

## 今までの三角形の作り方
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="JjeGMQd" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/JjeGMQd">
  CSS Masking - Fade out UI</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

今までは、三角形を↑このように`border`を駆使して作成していました。

どうしてこうなるかは、省略しますが、本来のプロパティとは違う使い方でうつくしくないですよね！

この方法のいけてないポイントは以下の通りです。

+ **1. 指定の大きさの三角形をつくるのに、`border-width`を使うところ**
    + 本来、`border-width`は、要素の境界の幅を指定するプロパティで、要素の大きさを指定するプロパティではありません。
    + 理想は、`widht` と `height`プロパティを使って要素のサイズは指定することですよね！
+ **2. 指定の色の三角形をつくるのに、`border-color`を使うところ**
    + 本来、`border-color`は、要素の境界の色を指定するプロパティで、要素の色を指定するプロパティではありません。
    + 理想は、`background-color` プロパティを使って要素の色は指定することですよね！
+ **3. 任意の三角形が作りにくい・作れない**
    + `border`を使った三角形だと、正三角形や直角三角形といった特定の三角形を意図的につくるのは難しいです。
    + 理想は、正三角形とか、直角三角形が、容易に作れることですよね！

こんな感じに、borderで三角形つくることにむずむずするワケです。

## これからの三角形の作り方
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="vYQLdyJ" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/vYQLdyJ">
  CSS - Triangle - sample1</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

これからの方法は↑このように、`clip-path`を使って作ります。


`clip-path`は、要素を任意の形にクリップできるプロパティになります。
以下のようにクリップする形を変えることで、上下左右どの向きの三角形でもつくることができます。

```css
/* 上向き ▲ */
.up {
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

/* 右向き ▶︎ */
.right {
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

/* 下向き ▼ */
.down {
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

/* 左向き ◀︎ */
.left {
  clip-path: polygon(0 50%, 100% 0, 100% 100%);
}
```



この方法だと、プロパティをプロパティ通りに使うことができるので、むずむずしません。
また、三角形を変形させることができるところもポイント高いです。


### 正三角形
正三角形は、底辺と高さの関係はこうなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/708bded9-1ad1-804b-b7f0-6a0816832934.png)


この関係性を使って、以下のようなスタイルを当てることで正三角形にできます。

```css
.triangle {
  height: calc(60px / 2 * tan(60deg));
  width: 60px;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
```

### 直角二等辺三角形
直角二等辺三角形は、底辺と高さの関係はこうなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/67f1c0ac-7526-ea6d-2c23-79e76cac4f59.png)

この関係性を使って、以下のようなスタイルを当てることで垂直三角形にできます。

```css
.triangle {
  height: calc(60px / 2);
  width: 60px;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
```

### 不等辺三角形
`clip-path`を使うと不等辺三角形もつくることができます。イメージはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/f411290a-9776-6736-1939-ba9aed006282.png)

```css
/* 鋭角三角形 */
.acute-triangle {
  height: 30px;
  width: 60px;
  clip-path: polygon(75% 0, 100% 100%, 0 100%);
}

/* 鈍角三角形 */
.obtuse-triangle {
  height: 30px;
  width: 60px;
  clip-path: polygon(100% 0, 50% 100%, 0 100%);
}

```

## まとめ

この記事では、CSSで三角形をつくるベストプラクティスを紹介しました。

今までの`border`を使った三角形の作り方だと、
本来のプロパティの使い方とは違ったり、直感的に意図した形状の三角形が作れなかったりと、
とってもムズムズしていました。

ただ、`clip-path`を使った三角形の方だと、
直感的で、意図した形状の三角形が作りやすく、ムズムズしない感じでつくることができます。

この記事を読んだあとに、CSSで三角形をつくる時は、ぜひ`border`ではなく、`clip-path`で作っていただけると嬉しいです。



## 追記

`clip-path: polygon()`の利用可能ブラウザは以下のリンクをご確認ください。

https://caniuse.com/mdn-css_properties_clip-path_basic_shape


例のheightを決めている`tan()`の利用可能ブラウザは以下のリンクをご確認ください。

https://caniuse.com/mdn-css_types_tan

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510