【CSS】IE非対応のCSSテクニック備忘録【初心者】

# はじめに
夜空に瞬く星の数ほどのエンジニアを幾度となく苦しめてきたIEがサポート終了してもうすぐ6ヶ月（記事投稿時点）が経ちます。
あの空に浮かんでいる星の中にはIEに屈して星になった人もいるのかなーと思いながら日々の業務に明け暮れています。

今年から新卒でエンジニアになった僕はその苦しみはほとんど味わうことなくIE終了の時を迎えることができましたが、
普段実装中CSSプロパティのブラウザ対応状況を調べた際、主要ブラウザの中でIEだけが対応していないものの多さに日々震えています。。

今回は今年１年で学んだことも含めて、
自身が見返すことができるようにそんなCSSプロパティをまとめておこうと思いました。

## 目次
* [比較関数](#比較関数)
* [内因性サイジング](#内因性サイジング)
* [画像関連](#画像関連)
* [その他のプロパティ](#その他のプロパティ)


## 比較関数
いきなりプロパティではないですが、CSSの比較関数min(),max(),clamp()です。

最大値、最小値を計算式で定義することができます。
値はコンテキスト(%,em,rem,vw/vh)に依存します。
この関数を使ってレスポンシブな記述をメディアクエリを使用せずに簡単に書くことができます。

### min()
min()関数は最大値を設定することができます。
下記のような記述の場合、
.elementの横幅は300pxを越えるまで50vwとして表示され、それ以上では300pxで固定されます。
```.css
.element {
  width: min(50vw, 300px); /* (推奨値, 最大値) */
}
```
### max()
同様にmax関数は最小値を設定することができます。
下記のような記述の場合、
.elementの横幅は300pxより小さくはならず、それ以上では50vwとして表示されます。
```.css
.element {
  width: max(50vw, 300px); /* (推奨値, 最小値) */
}
```
このmax関数を使ってレスポンシブな文字サイズの最小値を設定することもできます。
```.css
.text {
  font-size: max(3.6vw, 11px); 
}
```

### clamp()
clamp関数は最大値と最小値を組み合わせることができます。
下記のような記述の場合、最小値を100px、最大値を500pxとして50vwの値をとります。
```.css
.element {
  width: clamp(100px, 50vw, 500px); /* (最小値, 推奨値, 最大値) */
}
```
<details><summary>サンプルコード</summary>
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PoagjXM" data-user="Right-88" 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/Right-88/pen/PoagjXM">
  min() max() clamp()</a> by rhrh__8 (<a href="https://codepen.io/Right-88">@Right-88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</details>

__参考__

https://coliss.com/articles/build-websites/operation/css/css-about-min-max-clamp.html

[MDN min()](https://developer.mozilla.org/ja/docs/Web/CSS/min)
[MDN max()](https://developer.mozilla.org/ja/docs/Web/CSS/max)
[MDN clamp()](https://developer.mozilla.org/ja/docs/Web/CSS/clamp)
[Can I use](https://caniuse.com/?search=css%20clamp)


## 内因性サイジング
内因性サイジングの値 min-content, max-content, fit-contentを使用して
要素のサイズをコンテンツの中身に応じて指定することができます。

### min-content, max-content
min-content, max-contentは要素の内在的な最小幅、最大幅を表します。
またテキストコンテンツの幅にmin-contentを使用した場合 __最も長い単語__ の幅で固定されます。

↓gridアイテムの幅を固定したい時などに活用できます。

```.css
.item {
    display: grid;
    grid-template-areas:
    "area1 area2"
    "area1 area3"
    "area1 area4";
    grid-template-rows: max-content max-content 1fr;
}
```

### fit-content
fit-contentはmin-contentとmax-contentを組み合わせたもので、
この値を指定した要素はmax-content以上のサイズにはならず、さらにmin-contentより小さくはなりません。
img要素の幅をビューポートを超えても親要素の幅に合わせて表示させたい時などに使えます。

サンプルコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="vYrMJEw" data-user="Right-88" 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/Right-88/pen/vYrMJEw">
  min-content, max-content</a> by rhrh__8 (<a href="https://codepen.io/Right-88">@Right-88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


__参考__

https://coliss.com/articles/build-websites/operation/css/intrinsic-sizing-in-css.html

[MDN max-content](https://developer.mozilla.org/ja/docs/Web/CSS/max-content)
[MDN min-content](https://developer.mozilla.org/ja/docs/Web/CSS/min-content)
[MDN fit-content](https://developer.mozilla.org/ja/docs/Web/CSS/fit-content)
[Can I use](https://caniuse.com/?search=max-fit-content)


## 画像関連

### object-fit
object-fitプロパティは要素をコンテナ内にどのように収めるかを
background-sizeのように指定することができます。
```.css
.img {
  object-fit: contain; /*縦横比を維持しつつコンテナ内に収まるよう表示*/
  object-fit: cover; /*縦横比を維持しつつコンテナにフィットするように縦横中央に表示。はみ出る部分はトリミングされる*/
  object-fit: fill; /*初期値。縦横比を無視してコンテナ内に収まるよう表示*/
  object-fit: none; /*画像のリサイズはせず縦横中央に表示*/
  object-fit: scale-down; /*「contain」を指定しつつ画像がコンテナーをはみ出る時は「none」を指定*/
}
```
### object-position
object-positionプロパティはコンテナ内の置換要素[^1]の配置を
background-positionのように指定することができます。
```.css
.img {
  object-position: 50% 50%; /*初期値*/
  object-position: center top;
  object-position: 100px 50px;
}
```
[^1]:置換要素…img要素やvideo要素、iframe要素などCSSの整形モデルとは独立して表現される外部オブジェクト。
https://developer.mozilla.org/ja/docs/Web/CSS/Replaced_element

object-fit・object-positionを使うことでサイズの違う画像をトリミングすることができます。

サンプルコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBKwXKG" data-user="Right-88" 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/Right-88/pen/qBKwXKG">
  object-fit, object-position</a> by rhrh__8 (<a href="https://codepen.io/Right-88">@Right-88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

__参考__

https://webdesignday.jp/inspiration/technique/css/7976/


[MDN object-fit](https://developer.mozilla.org/ja/docs/Web/CSS/object-fit)
[MDN object-position](https://developer.mozilla.org/ja/docs/Web/CSS/object-position)
[Can I use](https://caniuse.com/?search=css%20object-fit)


### aspect-ratio
aspect-ratioプロパティはボックスの推奨アスペクト比を指定することができます。
主に画像を含む要素に使用して、アスペクト比を固定することに使えます。

img要素にいちいちwidth,heightを指定しなくても簡単にレイアウトシフト[^2]の対策をすることができます。
[^2]: レイアウトシフト……Webページの読み込みの際画像が読み込まれるまでに画像分のスペースが無いため、
画像が読み込まれた時にレイアウトがずれてしまうこと。UX上大変よろしくないです。。
https://www.e-webseisaku.com/column/marketing/6833/

```.css
.img {
  aspect-ratio: 16 / 9;
  aspect-ratio: 600 / 450; /*比率を計算してくれるので画像サイズをそのまま入れることもできる*/
}
```

前述したobject-fitプロパティと合わせることで、CMSなどで画像が更新されるサムネの実装をするなどの際に
違うサイズの画像が入っても自動でトリミングして表示することもできます。
```.css
.img {
  aspect-ratio: 480 / 320;
  object-fit: cover;
  object-position: center center;
}
```

[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/aspect-ratio)
[Can I use](https://caniuse.com/?search=aspect-ratio)

### image-rendering
image-renderingプロパティはブラウザの画像がユーザー操作などによって拡大・縮小された時の線画指定をすることができます。
```.css
 img {
  image-rendering: auto; /*初期値。それぞれのユーザーエージェントに依存した表示になる*/
  image-rendering: crisp-edges; /*画像処理に円滑化やぼかしを行わないためエッジの効いた表示となる*/
  image-rendering: pixelated; /*画像の拡大時にはエッジの効いた表示となり、縮小時にはautoと同様の表示になる*/
}
```
画像のぼやけが気になる際は使ってみてもいいかも…
※Chromeで画像がぼやける時は
 `transform: translateZ(0);` や `backface-visibility: hidden;`
を指定してあげた方が効果がある気がします。。

__参考__

https://sho-log.com/chrome-image-blurred/

[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/image-rendering)
[Can I use](https://caniuse.com/?search=image-rendering)

## マスキング

### clip-path
clip-pathプロパティは要素を指定した形で表示するためのクリッピング領域を作成することができます。

|　指定できる値　||
|:-:|:-:|
| inset() |　矩形。四つの辺を定義できる　|
| circle()|　円形　|
| ellipse()| 楕円形  |
|  polygon() | 複数の異なるセットを制御して様々な図形を作成できる  |
| path()  | SVGのパスを指定してその形の領域を作成できる  |

```.css
img {
  clip-path: circle(50px at 20% 40%);
  clip-path: inset(5% 10% 10% 5% round 15px);
  clip-path: polygon(53% 26%, 100% 50%, 53% 74%, 0% 100%, 25% 50%, 0% 0%);
  clip-path: path('M140 20C73 20 20 74 20 140c0 135 136 170 228 303 88-132 229-173 229-303 0-66-54-120-120-120-48 0-90 28-109 69-19-41-60-69-108-69z');
}
```
at~でクリッピングする座標位置を指定したり、round~で角丸の指定をすることもできます。

<details><summary>サンプルコード</summary>
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRGLMNE" data-user="Right-88" 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/Right-88/pen/GRGLMNE">
  clip-path</a> by rhrh__8 (<a href="https://codepen.io/Right-88">@Right-88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</details>

[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/clip-path)
[Can I use](https://caniuse.com/?search=css%20property%20clip-path)

### mask-image
mask-imageプロパティを使うと指定した画像で要素をマスクすることができます。
値にグラデーションを指定することもできます。
```.css
.mask {
  mask-image: url(mask.svg);
  mask-image: linear-gradient(to top, transparent 5%, white 100%);
}
```

[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/mask-image)
[Can I use](https://caniuse.com/?search=css%20mask-image)

## その他のプロパティ

### gap (flex)
自分の中で早く何も気にせず使いたいプロパティNo.1とも言われているflexのgapです。
flexアイテム間の余白をコンテナから指定することができます。
```.css
.list {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 20px; /* 縦方向の余白 横方向の余白; */
}
```
flexアイテム間のみの余白を指定することができるので、
今までflexアイテムにmargin-topをつけて、コンテナのmargin-topにネガティブマージンをつけて……
というように対応していたカラム落ちするカードリストなどの余白も一発で指定することができます。

<details><summary>サンプルコード</summary>
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="XWYQemw" data-user="Right-88" 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/Right-88/pen/XWYQemw">
  Untitled</a> by rhrh__8 (<a href="https://codepen.io/Right-88">@Right-88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</details>

:::note warn
iOS Safari はバージョン14.５から、Chromeはバージョン84から対応され、
それ以前のバージョンのユーザーもまだ合わせて2.3%ほどいるため(2022年12月10日現在)
使用の際には対応ブラウザ等の検討が必要だと思います。
:::

[MDN](https://caniuse.com/?search=gap)
[Can I use](https://caniuse.com/?search=gap%20flex)

### mix-blend-mode
photoshopやillustratorなどのデザインツールには標準搭載されているレイヤーを重ねた時の混合指定を
CSSで指定できるプロパティです。
`mix-blend-mode: exclusion;`を指定することで、固定した要素の色を背景によって反転させることができます。

サンプルコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBKwPLR" data-user="Right-88" 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/Right-88/pen/qBKwPLR">
  mix-blend-mode</a> by rhrh__8 (<a href="https://codepen.io/Right-88">@Right-88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

__参考__

https://ics.media/entry/7258/

[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/mix-blend-mode)
[Can I use](https://caniuse.com/?search=css%20mix-blend-mode)

## まとめ
今回は特に代表的なものをまとめましたが、この他にもIEが終了して使いやすくなったCSSは沢山あります。
この時代に生まれたことを感謝してこれらのプロパティを積極的に使い、新時代のエンジニアを目指していきたいと思います。