年末まで毎日webサイトを作り続ける大学生 〜25日目 画像の縦横比を最大限で保つ、画像の上にテキストを表示させる（中央配置）〜

##はじめに
こんにちは！最近週末は温泉に通っている@70days_jsです！
webサイト制作でお金を稼ぐために年末まで毎日webサイトを作っております。
今日は画像を縦横比を保ったままなるべく大きくボックス内に表示させる、画像の上にテキストを表示させる、ということをしました。
扱う技術レベルは低いですが、同じように悩んでる初心者の方を勇気付けられれば幸いです。
今日は25日目。(2019/11/12)
よろしくお願いします。

##サイトURL
- https://sin2cos21.github.io/day25.html


##やったこと
今日やったことは大まかに分けると3つです。

1. 画像の縦横比を保ったままボックス内で最大表示する（原寸サイズ以上にはならない）
2. 画像を中央配置にする
3. テキストを画像の上に被せ、かつ中央配置にする


とりあえずまずは実装を見てみましょう！↓
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/5435bb5a-b06b-5ff7-eb72-6a94222d2bf3.gif)


というわけで実装自体はシンプルでメインは仕組みの理解です。今日は前々からやりたかったテキスト on 画像の仕組みが理解できたので嬉しいです。
それでは1から順に説明していきます。


###1. 画像の縦横比を保ったままボックス内で最大表示する（原寸サイズ以上にはならない）
これはとてもシンプルです。

```css
    max-width:100%;
    max-height:100%;
```
この二行を加えるだけで画像はボックス内で縦横比を保ったまま最大でいてくれます。
maxを100%にすることで、画像の縦か横のどちらかがボックス最大までリサイズしてくれるという寸法です。maxが100%なので、小さい分にはいくらでも縦横比を保ったままリサイズしてくれますが、原寸以上のサイズには対応しません。

###2. 画像を中央配置にする
次。画像の中央配置ですが、これはflex boxを使うのが一番早いという結論になりました。

htmlがこうあってimgを中央配置したいのなら、

```html

<body>
    <div id="image_wrapper">
        <img class="background_image" src="day24_image/photo4.jpg" alt="テントの画像">
        <h2 class="text_on_image">テント泊</h2>
    </div>
</body>
```
idがimage-wrapperのdivに

```css
#image_wrapper {
    background-color: rgba(0, 0, 0, 1);
    width: 100vw;
    height: 100vh;
    /* 画像を真ん中に配置するためのflex */
    display: flex;
    justify-content: center;
    align-items: center;
}
```
とdisplayをflexにしてあげると解決です。
flexだったらimgの下にあるh2も反応するのではないかと思うかもしれませんが、後述しますがh2は画像の上に被せるためにpositionをabsoluteにするので全く問題ないです。
というわけで、子要素が一つしかなく、positionがabsoluteでもfixedでもない要素を中央配置したい場合、flex boxを使うのが一番楽です。
逆にいうと、要素を中央配置したい場合はこの条件にいかに当てはめるかという考え方もできると思いました。


###3. テキストを画像の上に被せ、かつ中央配置にする
最後にテキスト on 画像について説明します。
テキストを画像に被せること自体はとても簡単です。

```css
    /* 要素同士を被せるためにはabsoluteかfixedを使わないといけない */
    position: absolute;
    top: 値;
    left: 値;
```
positionをabsoluteにして、topやleftの値を画像の上に設定すれば解決です。
ですが、ここで困ったことが起こります。例えば画像が中央配置になっていて、テキストのpositionをtop,leftとも50%にしても中央にはなりません。
これは要素の端の部分が50%地点に置かれるためです。（残念ながら、要素の中央部分が50%地点ではないのです。。。）
と、ここでこの問題を解決するために、transformプロパティを使います。transformプロパティで行うことはtopやleftで行うことと同じです。
言葉では理解しづらいので図にしてみました。↓
![スクリーンショット 2019-11-12 21.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/6abab8ee-385b-b951-df78-b165480152cf.png)

topやleftで指定しても要素の端がきて困るのなら、transformでも反対から位置を指定してやれば、両者の値が平均されて要素がちょうど真ん中にくるという仕組みです。

上の図は簡略化のため横方向のみを真ん中に置くだけですが、縦方向もtranslateYとtopを指定して真ん中にすれば、縦横両方とも真ん中なので中央配置が実現します。

cssの表記はこうなります。↓

```css

.text_on_image {
    position: absolute;

    top: 50%;
    left: 50%;
    transform: translateY(-50%) translateX(-50%);
    /* または
    bottom: 50%;
    right: 50%;
    transform: translateY(50%) translateX(50%); */
}
```

コメントでも書いていますが、top,leftを使わなくてもbottom,rightの指定でも可能です。その場合はtransformの値も要素がちょうど真ん中にくるよう書き換える必要があります。

##感想
晩御飯を作る前に今日の分を作ろうと思ってたら、意外とハマって結局2時間も腹ペコのままコーディングする羽目になりました。特にテキストの中央配置が意外と時間を食いました。最初はなぜtop,leftだけで中央配置にならないのか疑問でしたが、「要素の端が指定した部分にくる」ということと、transformプロパティを知るとなるほどと思いました。でもこれ初見殺しだと思うので、いずれ直接要素を中央配置できるように改定されるんじゃないかな・・・。とはいえ、これだけ知っていればもうabsoluteと併用して自由自在に要素を配置できるので気分アゲアゲです。よし、晩御飯食べてきます！

最後までお読みいただきありがとうございます。明日も投稿しますのでよろしくお願い致します。

##参考
1. 【CSS】img画像の縦横比を保ったままボックス内に収める方法 | フリーランス ジャーナル(https://1design.jp/web-development/css/1844)
2. CSS「position:relative」と「position:absolute」で画像や文字を重ねる方法(https://naifix.com/relative-absolute/)

とても勉強になりました。ありがとうございます！