HTML/CSS レスポンシブ対応 個人的まとめ

# 概要
フロントトエンドの学習記録。
レスポンシブなレイアウトをCSSで実現する方法。
キーワードは以下の通り。

- ビューポート
- メディアクエリ
- widthのパーセント指定
- flex-box

# キーワドの詳細

## ビューポート

htmlのheader内に、metaタグとして埋め込みを行う。
モバイルデバイス（スマートフォン・タブレットなど）用の設定で、レスポンシブデザインを適応する際に必要な端末情報を取得して埋め込む。
主に、後述するメディアクエリの判定基準に使用される。

```html
<meta name="viewport" content="width=device-width, initial-scale=1.0">
```

**device-width: モバイル端末のCSSピクセル(コーディンする際の画面横幅)**
※解像度には、CSSピクセル(HTMLコーディングで気にする) と デバイスピクスセル(画像で気にする)がある
例) iPhone X : CSSピクセル => 375 x 812 / デバイスピクセル => 1,125 x 2,436

**initial-scale: ベージ表示時の初期拡大倍率**
適切に、メディアクエリを用いてレスポンシブ対応する場合は1.0指定で概ね問題ない。
複数デバイスへの対応を力技で拡縮率だけで乗り切ろうとすると、1.0をjsでゴニョゴニョする必要もある、

なお、ビューポートは、CSS以外では、JavaScriptのwindow.innerWidth・innerHeightにも影響がある。

## メディアクエリ

Media Queries

デバイスの画面サイズ別に、適応するCSSを変える(上書きする)などの場合に使用する、
@mediaで始まり、そのあとに、max-width か min-width　でCSSの適応の境界値を設定する。
境界値となる値は、 **ブレークポイント** と呼ぶ。
ブレークポイント前にメディタイプを挟むこともできる。 
@media  screen | tv | printer  みたいな感じ。省略するとallになる。

なお、ブレークポイントの指定はどちらも境界値を含む。
> ‘min-’ or ‘max-’ prefixes to express "greater or equal to" and "smaller or equal to"　
[https://www.w3.org/TR/css3-mediaqueries/#media1](https://www.w3.org/TR/css3-mediaqueries/#media1)

以下に使用例を示す

```css

@media (max-width: 1000px) {
/* 最大画面サイズが1000px "まで(x <= 1000)" 適応したいCSS定義 */
}

@media (min-width: 1000px) {
/* 最大画面サイズが1000px "から(x >= 1000)" 適応したいCSS定義 */ 
}

@media (min-width: 1000px) and (max-width: 1500px)  {
/* 最大画面サイズが1000〜1500px まで適応したいCSS定義 */
}
```

**実践的な使い方**
実践的には、 **スマホ / タブレット / デスクトップPC** の3つでブレークポイントを設定するケースが多い。
ブレークポイントを沢山設定し過ぎてもメンテナンスしにくいので、これくらいがちょうど良い。
どの値をブレークポイントとするかだが、昨今のスマホ画面サイズの大型化の流れなどで、変化してきているようだ。
その時の、有識者がまとめている定番の値を、ググって適応するのが良さそう。
雰囲気的には　400-600 | 800-1024 に境界値を設けているところが多そうだ。 


一応、現時点での、個人的な設定を記載する。
デバイスが徐々に大型化(多様化)する流れを感じつつ、少し大きめなところで線を引いてみた。

**3つに分けるケース**
モバイルファーストで作成しつつタブレットやデスクトップPCにも、きっちり出し分け対応したい場合。

```css
/* スマホ用 (<= 640px) */
@media (min-width: 640px) {
}

/* タブレット用 ( <= 1024) */
@media (min-width: 1024px) {
}
```

**２つに分けるケース**
デスクトップPCの画面をメインとして、タブレットやスマホなども最低限見える程度に対応したい場合。
※ iPad Pro11の縦使用をPCとみなしたい場合は834を境界値に。

```css
/* スマホ/タブレット用 (<= 900px) */
@media (min-width: 900px) {
}
```

## widthのパーセント指定

メディアクエリを使って、それぞれのブレークポイント別に、コンテンツの表示件数を変える場合には、
widthをパーセント指定する。

以下に想定するケースを書く
・スマホ表示時には１つだけ newsコンテンツ を出す。
・タブレット表示時には２つ newsコンテンツ を横並びで出す。
・デスクトップ表示時には4つ newsコンテンツ を横並びで出す。

これをこうする。

```css
.news {
  width: 25%;
}

/* スマホ用 (<= 640px) */
@media (min-width: 640px) {
  .news {
    width: 100%;
  }
}

/* タブレット用 ( <= 1024) */
@media (min-width: 1024px) {
  .news {
    width: 50%;
  }
}
```

**box-sizing: border-box**

調整をかけたいブロック要素に対して、paddingが設定された場合、
単純にパーセント指定だけだと厳しい局面がある。
なぜなら、paddingに対しては、パーセント計算が適応されないからである。
なので、画面サイズの小さい端末でみたときに、相対的に余白が大きく適応されて違和感が出てしまう。
また、floatで横並びレイアウトを組んでいた場合サイズが収まりきらなくて、箱落ちしてしまう。
これを防ぐために、 **border-box** 指定を使う。

```css
* {
  box-sizing: border-box;
}
```

これにより、パーセント計算の時に、 *余白も含めて(borderまで含めて）* パーセント計算対象にしてくれるので、表示がいい感じに整う。
border-boxを使用しない場合は、旧来のcss内で、padding値を計算する方法もある。
なお、border-boxはmarginには適応されないので注意。 


## flex-box

フレキシブルにレイアウトを組むために入った仕組み。
レスポンシブデザイン向けの対応でよく用いられる。

**使い方**

- 親要素に display:flex (子要素がインライン要素の場合はinline-flex)と並べる指向性を宣言する
 - flex-direction:並べる方向 => [row| column]-[ | reverse] で4パターンから指定 
 - flex-wrap:折り返しルール => [nowrap | wrap | wrap-reverse]から指定
 - flex-flow: direction/wrap記述のショートハンド =>  flex-flow: row wrap;
  
- 親要素にflexの全体での細かい動作適応設定を行う。(整列方法)
 - justify-content: 水平の整列ルール => [flex-start| flex-end | center | space-between | space-around]
 - align-items: 垂直の単一行整列ルール => [stretch | flex-start | flex-end | center | baseline] 
 - align-content: 垂直の複数行整列ルール(wrap時) =>  justify-contentと同じ指定


- 子要素で、要素個々の適応設定を行う。
 - order: 順番を制御 => あくまでも見た目だけ(DOMの並びは変わらないのでjsで要素抜くときは注意)
 - flex-grow: 相対的な拡大率 => 他要素を１で、特定要素だけ２にすると表示上幅２倍の比率で表示されるになる 
 - flex-shrink: 相対的な縮小率 => growの逆
 - flex-basis: 子要素のベースの幅 => [auto | 200px | 25%] などで指定。
 - flex: grow/shurink/basisのショートハンド => flex: 0 1 30%;
 - align-self: (親要素をからの)子要素の垂直表示揃え => [auto | stretch | flex-start | flex-end | center | baseline ]


**具体例**
parante: .container
child: .item　x N個 
みたいな要素で構成されるマークアップ構造があったとする。

```css
.container {
  display: flex;
  /** 子要素をrow/columnで並べ、reverseで順方向か逆方向かを指定。初期値はrow **/
  flex-direction: row-reverse;
}

.item1 { flex-grow: 2; }
.item2 { flex-grow: 3; }
.item3 { flex-grow: 1; }
```

# 具体例

レスポンシブデザインのパターンとしては下記が良記事。
５つの代表的なレウアウトパターン・形状の変化と実現方法、メリット or デメリットが説明されている。

- mostly fluid
- column drop
- layout shifter
- tiny tweaks
- off canvas 

> https://developers.google.com/web/fundamentals/design-and-ux/responsive/patterns