CSSをリスキリングしてみて「あ、これ使ってみよう」と思ったアレコレ

webサイト制作を10年近く携わってきましたが、
CSSにおいては、昔はfloatを使って横並びレイアウトを作成する方法を用いていました。

その後、CSSにはflexboxという素晴らしいプロパティが登場し、横並びのレイアウト作成がずっと簡単になりました。
この変化はとても素晴らしいものでしたが、最近ではさらに進化したgridレイアウトが登場し、より柔軟性のあるデザインを構築することが可能になりました。

また、IE(Internet Explorer)のサポートがなくなり、モダンなCSSプロパティを自由に使用できる環境が整ってきました。
このような状況を受けて、再びCSSプロパティのリスキリングに取り組むことにしました。
特に注目して活用してみたいcssをいくつかピックアップしてみます。

## min()・max()・clamp()
このプロパティって最大値や最小値を決めれるんでしょ？最小と最大の間をいい感じに大きさを決めてくれるんでしょう？
くらいに思っていましたが、ちゃんと理解していない。。。

以下使い方例です。
コンテンツ幅を100%とし、最大幅をmax-widthで指定するような場面がよくあると思います。
そんな時はmin()を使って1行で記載することができます。

```css
.contents{
  width:100%;
  max-width:1200px;
}
```
↓
```css
.contents{
  width:min(100%, 1200px);
}
```
一行で設定できるのはいいですね。
（最大値を設定できるから`max`って使いたくなりますが`min`が正しい）

### **フォントサイズで使うならclampが便利**
```
font-size: clamp(最小値, 推奨値, 最大値);
```
最小と最大は直感的にわかるけど、推奨値の`vw`ってどうやって計算すればいいか迷いませんか？
これは計算式があるみたいです。

```
最小のフォントサイズ　÷　最小のフォントサイズで止める画面サイズ　✕　100　= 推奨値
```

ということは、PCでの最小幅はブレイクポイントであることが多いと思うので、
「20px」（最小のフォントサイズ）÷「768px」(ブレイクポイント 768px ) ✕　100 = 2.6…

または以下のサイトで「最小フォントサイズ」と「最大値フォントサイズ」を入力して計算することも可能です。

https://min-max-calculator.9elements.com/
参考にしてみてください。

## display:contents

`display`プロパティって`inline`や`inline-block`とか`block`とか、あと`flex`や`grid`っていうのをよく使うと思いますが、`display:contents`って使ったことありますか？

これは`contents`を設定した要素は、DOMツリーから削除されたような扱いになります。

**今までは**
PCでは2カラムで、スマホでは1カラムの縦積みレイアウトがあったとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84007/530d9f98-0aee-efcd-a12d-988a07d1582e.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84007/7f0acb73-2adc-28b5-8590-fdc8bfea7152.png)

この時、leftとrightのボックスのpaddingやmarginを0にしたり、boxの余白を非表示をするような打ち消す設定が必要ですが、この`display:contents`を使うことでDOM自体をなかったものとし、wrapperだけで囲んだhtml構造にすることができます。

`display:none`のような子要素も含めて非表示にするわけではなく、そのDOMだけをなかったことにすることができ、簡単に縦積みレイアウトが作れます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="poQbzxY" data-user="migubou" 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/migubou/pen/poQbzxY">
  display:contents</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## inset

absoluteしたboxを上下左右のセンタリングするとき、top、right、bottom、leftにそれぞれ設定することが多かったと思います。
たとえば、
```css
.box{
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translateY(-50%) translateX(-50%);
}
```
こんなやり方があります。

それを`inset`を使うことで簡単に設定することができます。
```css
.box{
 position: absolute;
 inset: 0;
 margin:0 auto;
}
```
※画面を大きくしてみてください
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="BaGzyLo" data-user="migubou" 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/migubou/pen/BaGzyLo">
  Untitled</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## place-items、place-self
flexboxやgridを使って子要素の位置を決める時につかうプロパティ`align-items`と`justfy-contents`がありますが、こんな感じで設定していました。
```css
.div{
 display:grid;
 align-items:center;
 justfy-contents:center;
}
```

これ、ショートハンドで簡単に設定できます。

```css
.div{
 display:grid;
 place-items:center;
}
```
これでOKです

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="yLQJyPz" data-user="migubou" 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/migubou/pen/yLQJyPz">
  grid-layout_place-items</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


### そもそも
そもそも似たプロパティで以下があります。
- align-content
- align-items
- align-self
- justify-content
- justify-items
- justify-self

これらの違い、理解しています？
（わたしは全然理解していませんでした。）

`align-xxx`系は縦軸の調整、`justify-xxx`系は横軸の調整になります。（それは知ってた）

で、
**xxx-content**
は、親コンテナの配置を決めるもの。（親要素に対して設定する）

**xxx-items**
は、子要素全体に影響を与える（親要素に対して設定する）

**xxx-self**
は、子要素単体に影響を与えるもの（子要素に対して設定する）

文字だとわかりにくいので実際に書いてみて理解を深めたほうが良さそうです。。。

**CordPen**
https://codepen.io/migubou/pen/gOQMGYw


## line-clamp
ブログなどでカードタイプのレイアウトがあった時に、
そのカードの中の文字が多かったらどう処理してます？
文字数が多かったときは、特定の文字数を超えた文を「…」（三点リーダー）にして省略することができます。

```css
.text{
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOQMGYw" data-user="migubou" 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/migubou/pen/gOQMGYw">
  Untitled</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## any-hover

PC表示の時、ボタンにhoverエフェクトをつけることが多いですが、
スマホの時にはhoverエフェクトをつけたくない時、今まではmedia queryでスマホ表示のスタイルにhover疑似要素に対して打ち消すような指定をしていました。

```css
a {
  color: #327caf;
    &:hover {
      color: #205875;
  }
}
```
この書き方は、スマートフォンでボタンをタップするとホバーをしている状態でキープされてしまいます。
（ホバーしっぱなし状態）

これからはany-hoverというmedia queryを使うことで簡単に設定することができます

### **`@media (any-hover: 値)`**

複数の入力デバイスがある場合、いずれかがホバーが利用できるデバイスが判定するメディア特性です。

| メディアクエリ | 判定 |
| --- | --- |
| @media (any-hover: hover) | 入力デバイスのいずれかに、ホバーに対応している入力デバイスが含まれる場合 |
| @media (any-hover: none) | 入力デバイスのいずれかに、ホバーに対応している入力デバイスが含まれない場合 |

```css
@media (any-hover: hover) {
// hover対応しているデバイの時だけ対応
  a:hover{
     background-color: orange;
  }
}
```

このように書くことで、hoverに対応したデバイスの時だけスタイルを適応させることができます。


## justify-content:space-evenly;
`justify-content`は`space-between`をよく使うんですが、`space-evenly`があることを最近知りました。

`justify-content: space-between;` は、横並びの要素を両端揃えで均等に配置する指定です。
`justify-content: space-around;` は、それぞれの要素に均等な余白をつける指定です。要素の両側に均等な余白をつけるため、要素どうしの余白は両端の余白の2倍の大きさになります。
`justify-content: space-evenly;` は、すべての余白を均等にする指定です。こちらの指定では、両端を含めたすべての余白が同じ大きさとなります。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="yLQJzEZ" data-user="migubou" 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/migubou/pen/yLQJzEZ">
  Untitled</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## flexboxでもgapを使う
`gap`はgridレイアウトを使っているときの間隔を指定するものという理解でしたが、これって前はgridだけで使えるプロパティかとおもっていましたが、今はflexboxでも使うことができます。
flexboxで`gap`が使えるようになっていたの知ってましたか？
```css
// 今はflexboxにもgapが使える
.box{
 display: flex;
 gap: 10px;
}
```

## font-feature-settings:"palt";

デザイナーが作ったデザインの文章がプロポーショナルフォントで文字詰めが自動でなっている時、
cssではどう設定していますか？`letter-space`使ってます？
そんな時は、この`font-feature-settings`プロパティを使うことで、プロポーショナルフォントのようなデザインを設定することができます。
デザインにこだわる場合はこれを活用することができます。

このCSSプロパティを使ったからといってすべてのフォントで自動で文字詰めされるわけではありません。
利用できる条件は、OpenTypeフォントであることとプロポーショナルな情報が含まれていることが必要です。
有名なフォントでいうと
- 「ヒラギノ角ゴシック体」
- 「ヒラギノ明朝体」
- 「游ゴシック体」
- 「游明朝体」
- 「Noto Sans CJK JP」
あたりのフォントで利用できます。

※ Windows環境で馴染みある「メイリオ」は日本語部分が等幅として設計されているため、プロポーショナルメトリクスの情報は含まれていません。
そのため、**「メイリオ」に対してはプロポーショナルメトリクスで字間が詰まりません**。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRwqMym" data-user="migubou" 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/migubou/pen/GRwqMym">
  font-feature-settings</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## width: max-content;
`max-content`は、コンテンツの中身の一番長い文章を最大値としてボックスの幅を指定することができます。
（「長い文章」とは改行までの文章）
逆に`min-content`は、コンテンツの中の一番短い文章を最大値としてボックスの幅を決めることができます。
これも実際に書いてみて試してみると理解が深まると思います。

※画面を大きくしてみてください。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="BaGzwvr" data-user="migubou" 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/migubou/pen/BaGzwvr">
  Untitled</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## CSSの新しいビューポート単位に、`svh` `lvh` `dvh`
`height:100vh`は画面の高さいっぱいにする時に設定しますが、
iosで100vhにすると、アドレスバーの高さ分が下に隠れて見えてしまいます。
これを解消するのは`dvh`を使うことで解消できます。

`svh`はアドレスバーを除いた画面表示領域
`lvh`はアドレスバーを含めた画面表示領域
`dvh`は`svh`と`lvh`の両方を動的に判別して指定してくれる

ぜひ`dvh`（daynamic view height）を使ってみましょう

## transformプロパティから独立して使える`translate`, `rotate`, `scale`
`translate`, `rotate`, `scale`は`transrom`プロパティで設定していましたが、
これが値ではなくプロパティで使えるようになりました。

```css
.box{
  transform: translate(20px, 20px)
             rotate(45deg)
             scale(1.5);
}
```
↓ 値をプロパティとして書けるようになりました
```css
.box{
  translate:20px 20px;
  rotate:45deg;
  scale:1.5;
}
```
この書き方は、`transform`で設定した内容を上書きしません。
```css
// 先のtransformを上書きしないので90degと90degで180deg回転します！
.box{
 transform:rotate(90deg);
 rotate:90deg;
}
```
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="OJaxgMd" data-user="migubou" 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/migubou/pen/OJaxgMd">
  translate,rotate,scale_single_propaty</a> by migubou (<a href="https://codepen.io/migubou">@migubou</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

ざっとですがこれらの使い方を覚えて、制作に活用していきたいと思います。