【HTML,CSS】任意の多角形で画像をトリミングする手法（clip-path=polygon）

#はじめに
ここではHTMLに埋め込む画像をCSSで任意の多角形にトリミングする手法について2つ紹介します．

Photoshopを用いて事前にトリミングをしておくこともできますが，CSSを用いることで画像の差し替えに対して柔軟に対応することができます．
1つ目は「擬似要素を用いた方法」で，2つ目は「画像の座標を用いたトリミング方法」です．
個人的には2つ目の「画像の座標を用いたトリミング方法」が手軽で便利に感じたため，より詳しく紹介したいと思います．

#目次
[1. 本記事で達成したいこと・目的](#1本記事で達成したいこと目的)
[2. 擬似要素を用いた方法](#2擬似要素を用いた方法)
[3. 擬似要素を用いた方法の問題点](#3擬似要素を用いた方法の問題点)
[4. clip-pathについて](#4clip-pathについて)
[5. clip-path=polygonの使い方](#5clip-path=polygonの使い方)
[6. 最後に](#6最後に)

#1.本記事で達成したいこと・目的
今回の目的は画像を以下のような形にトリミングすることとします．また視認性を上げるために上下に画像のトリミングには関係のない余白を持たせています．
![goal-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/b0c6a433-e5c9-c347-96a0-35d096fd3e35.png)



（元画像）![diagonal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/d013a5ab-5a0d-73be-4c0e-1b37ebb82dc0.jpeg)

元画像の左部分を上底>下底の台形で切り取られているという認識を持っていただければ理解しやすいと思います．

[お借りした画像の引用元はこちら](https://unsplash.com/photos/gMes5dNykus)




#2.擬似要素を用いた方法
まずは擬似要素を用いた方法を紹介します．この方法は直接画像を切り取るわけではなく，画像の不要な部分を擬似要素を用いて隠すことで画像がトリミングされたように見せるという考え方に基づいた手法です．

```css:style.css
.image::before{
    position: absolute; 
    z-index: 10; /* トリミングしたい画像よりも高い値 */
    top: 0;
    left: 0;
    display: block;
    width: 50%; /* 擬似要素の横幅 */
    height: 100%; /* 擬似要素の高さ */
    content: '';
    transform: translateX(-50%) skewX(-24deg);
    background-color: #f0f0f0; /* 背景色と揃える必要がある */

}
```

<br>
擬似要素部分を視認性を高めるために赤色にしました．
![process03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/4761bd04-2c62-59c0-ddc6-12a0092eb774.png)



transformの指定が少し複雑ですがそれ以外はとてもシンプルなので，一度transformを無視して擬似要素について考えると以下のような図形になります．

・高さが画像と同じ
・横幅は画像の半分のサイズ
・長方形

この図形に対してtransform: skewX(-24deg)を指定してやることで長方形全体が-24degrees傾き，平行四辺形になります．
また角度は最大360degreesであるため，-24degreesと336degreesは同値でありtransform: skewX(336deg)と指定しても同様の結果が得られます．

この平行四辺形をtransform: translateX(-50%)を指定してやることでX軸方向（左右方向）マイナスに50%平行移動させると今回の目的の図形になります．

![process01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/19359836-756e-213c-646b-2f636bfa5535.png)
![process02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/b92b8ca7-452b-df19-cb4f-2a2d36851441.png)
![process03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/4761bd04-2c62-59c0-ddc6-12a0092eb774.png)

#3.擬似要素を用いた方法の問題点
擬似要素は汎用的で便利な技術ですが，画像のトリミング目的で用いる場合は擬似要素の配色を背景の保護色にする必要があるという問題点があります．ただし背景が静的なコンテンツであれば，背景色を変更した時に少しコーディング面でコストがかかるだけで大きな問題はありません．
一方で背景色にグラデーションがかかっていたり背景が動的なサイトであった場合は，擬似要素にも同様の動きを追加してやる必要があり，コーディング面・サイトの読み込み面の両方のコストがかかってしまいます．

そのため画像単体で完結するトリミング方法が必要で，次に紹介する「画像の座標を用いたトリミング方法」が非常に有効です．


#4.clip-pathについて
画像の座標を用いたトリミングには[clip-path](https://developer.mozilla.org/ja/docs/Web/CSS/clip-path)というCSSプロパティを使用します．
プロパティの値にはトリミングしたい図形を指定することでその図形の内部領域が表示されます．
画像のトリミングにおいて非常に柔軟で便利なプロパティですが，[一部対応していないブラウザ](https://caniuse.com/?search=clip-path)があるという欠点もあります．

（値と対応する図形の例）

| 値 |対応する図形|
|:-:|:-:|
| inset |長方形|
| circle |円|
| ellipse |楕円|
| polygon |多角形|

clip-path1つで出来ることがかなり多いのでより幅広い使い方に関しては[スタイルシート](https://developer.mozilla.org/ja/docs/Web/CSS/clip-path)を参照してください．
ここではclip-path=polygonの使い方に限定して具体的に紹介します．

#5. clip-path=polygonの使い方
polygonとは多角形を意味し，多角形とは3つ以上の頂点を持つ図形を指します．つまり頂点を3つ以上持つ図形であれば理論上どのような形でもトリミング可能です．
直感的に頂点の数と処理速度が比例しそうだと思いましたが，Web上で調べても答えは分かりませんでした．いつか検証してみるのも面白いかもしれません．

clip-path=polygonを使用するにあたり，まずトリミングしたい図形の頂点の数を調べます．今回であれば台形なので頂点の数は4です．ここで図形の4つの頂点とその座標を左上から時計回りにA(X_a,Y_a)，B(X_b,Y_b)，C(X_c,Y_c)，D(X_d,Y_d)と定義します．
![process04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/7af83155-1d75-6eff-0a24-207cd7681020.png)

次に頂点A,B,C,Dの座標を求めていきます．
このとき，画像の左上の頂点の座標が(0%,0%)，右下の頂点の座標が(100%,100%)と定義されているため左上の頂点からのX軸方向，Y軸方向の距離をパーセント表示で表したものが各頂点の座標になります．左上が(0%,0%)であることは擬似要素と同じなので擬似要素が理解できていれば感覚的に分かりやすいかもしれません．
![process05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2400266/92a4633f-5819-1c84-9bd7-c991c1b846ed.png)


```css:style.css
.image{
    width: 100%;
    clip-path: polygon(35% 0%,100% 0%,100% 100%, 10% 100%) 
    /* clip-path: polygon(頂点Aの座標,頂点Bの座標,頂点Cの座標,頂点Dの座標) */
}
```

書き方は，clip-path: polygon(頂点Aの座標,頂点Bの座標,頂点Cの座標,頂点Dの座標)で大丈夫ですが，各頂点のX座標とY座標の間はコンマではなく半角スペースであることに注意してください．

#6.最後に
clip-pathは擬似要素と比較しても記述量が圧倒的に少なく，コードの可読性が上がるという面で自分に合った手法でした．対応力が高くとても便利だと感じたのでぜひ試してみてください．

また本記事は執筆者にとって初投稿となるため，至らぬ点や記述不足などありましたらご指摘いただければ今後に活かしたいと思います．

ここまでお付き合いいただきありがとうございました．