突貫！CSS！

<font color="deepskyblue">N予備校プログラミングコースの冬といえばこの　**:snowman2:<font color="plum">Advent Calendar</font>**、そして・・
 :sparkles:<font color="orange">　[**冬のプログラミングコンテスト**](https://progedu.github.io/webappcontest/2021/winter/entry/index.html) 　</font>:sparkles:が始まる季節！
<font color="mediumvioletred">
「**Webアプリのプログラミング部分はできた、、けど、、思ったようにボタンが・・、
　　部品が、、置きたい場所に、、配置できないんじゃああああああ**
![keyboard-crasher-angry.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/3f6e5818-278c-35e6-5647-0a3903ee869a.gif)
**うあああああああああああ！**」って方に向けたCSSの記事です。

## <font color="darksalmon">position: relative・absolute</font>
<font color="mediumvioletred">
おおよそ、これで配置はどうにかなります。positionプロパティ。
まずはpositionを使って、要素の**中央寄せ**を実装してみます。
**HTML**には**\<div>タグ一つ**のみです。
</font>

``` :html
<body>
<div id="A"></div>
</body>
```

``` :css
#A{
  position: relative;
  margin: auto;
  width: 500px;
  height: 200px;
  top:calc(100vh - 50vh - 100px);
  border: 4px double skyblue;
}
```


``position: relative;``
``margin: auto;``
``top:calc(100vh - 50vh - 100px);``
<font color="mediumvioletred">
**positionプロパティ**で、配置する場所を直接入力する方法です。まさに**力技**:fist_tone1:。
現在のCSSは**計算**で数値を設定できるので、遠慮なく使っていきます。
``calc();``
↑　これで計算できます。

``top:calc(100vh - 50vh - 100px);``
<font color="mediumvioletred">
「ブラウザの縦の大きさ」 - 「その５０％」 - 「divAの縦の200pxの半分100px」
で、画面中央に！ ｡ﾟ+.ヽ(´∀`\*)ﾉ ﾟ+.ﾟ
![center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/1c797a67-32f6-49dd-79b9-c3b5d5809ab3.png)
横も同じ様に設定してもOKですが、この例ではmargin: auto;で済んでしまうので省略。
練習として横の設定も変数にするのもいいのかも？
<font color="mediumvioletred">
むずかしい部分としては、**position属性**には**relativeとabsolute**と、似たものがあります。
２つの違いは原点　(**top: 0px;  left: 0px;** の場所)
</font>

``` :html
<body>
  <div id="A">
    <div id="B">B</div>
    <div id="C">C</div>
  </div>
</body>
```
``` :css
#A{
  position: relative;
  margin: auto;
  width: 500px;
  height: 200px;
  top:calc(100vh - 50vh - 100px);
  border: 4px double skyblue;
  color: deepskyblue;
}
#B{
  width: 300px;
  height: 50px;
  border: 4px double skyblue;
}
#C{
  width: 300px;
  height: 50px;
  border: 4px double skyblue;
}
```
<font color="mediumvioletred">
さきほど中央寄せしたboxに**B**と**C**というboxを追加しました。
現在、
**Aの子要素がBとC**、
**BとCの親要素がA**という状態です。
![reab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/5cf4f578-5826-9353-7d3f-348a5f7d46e7.png)
では、**Cにrelativeを付与**して、表示場所を **top:0px, left:0pxの左上端**にしてみます。

``` :css
#C{
  width: 300px;
  height: 50px;
  border: 4px double skyblue;
  position: relative;
  top:0px;
  left:0px;
}
```
<font color="mediumvioletred">
予想としては、２つともAの左上端、(0,0)の座標になり、BとCが重なるのではなかろうか？・・と思いきやどっこい、設定しても**見た目が変わりません**。次に **position: relative;** を　→ **position: absolute;** に書き換えてみます。

``` :css
#C{
  width: 300px;
  height: 50px;
  border: 4px double skyblue;
  position:absolute;
  top:0px;
  left:0px;
}
```
![abs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/4fa69f4b-c1e6-4168-ae5b-2bd52736d752.png)
<font color="mediumvioletred">
重なりました。これ、何が違うのかわかるでしょうか？ **position: absolute** の原点は、**周りの兄弟要素無視**して、**親要素Aの(0,0)が原点**となります。それに対し、**relative**は、**通常の表示場所が原点**となります。**C**を**position: relative;**に**戻して**位置を **top: -25px;** と設定してみると、**relative**がどこを**原点**にして移動しているのかわるかと思います。
<font color="mediumvioletred">
わかりにくかったら「**子要素は全部absolute！**」これで問題ないきがします。
<font color="mediumvioletred">
そして自由に要素を配置すると、要素同士が重なって、見せたいほうの要素が下に行ってしまい、見えなくなることがままあります。そういうときは、
``z-index: 数値;``
で**調整**します。いわゆる**レイヤー(階層)**みたいなものです。上にしたい方の数値を**整数**で**上**に**指定**すれば**OK**。

``` :css
#B{
  width: 300px;
  height: 50px;
  border: 4px double skyblue;
  position:absolute;
  top:0px;
  left:0px;
  z-index: 2;
}
#C{
  width: 300px;
  height: 50px;
  border: 4px double skyblue;
  position:absolute;
  top:0px;
  left:0px;
  z-index: 1;
}
```
<font color="mediumvioletred">
この例では、ボックスBが上になります。

注意点としては、
**positionがstatic(何も設定してない状態)では、z-indexは効きません。**
## <font color="darksalmon">Flex Box</font>
<font color="mediumvioletred">
次に、メジャーな機能が**フレックスボックス**。こちらは**親要素**と**子要素**の関係性が重要となってきます。下の**html**では**\<div id="A">が親要素**。その中に入ってる**\<div id="B">と\<div id="C>** が **子要素**です。

``` :html
<body>
  <div id="A">
    <div id="B">B</div>
    <div id="C">C</div>
  </div>
</body>
```
``` :css
#A{
  position: relative;
  margin: auto;
  width: 500px;
  height: 200px;
  top:calc(100vh - 50vh - 100px);
  border: 4px double skyblue;
  color: deepskyblue;
}
#B{
  width: 100px;
  height: 50px;
  border: 4px double skyblue;
}
#C{
  width: 100px;
  height: 50px;
  border: 4px double skyblue;
}
```
現在このように表示されます。
![flex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/b0a24319-0427-a03b-dceb-7b7dde2600c5.png)
<font color="mediumvioletred">
**フレックスボックス**は、**親要素**に設定を書き込んでいきます。

``` :css
#A{
  position: relative;
  margin: auto;
  width: 500px;
  height: 200px;
  top:calc(100vh - 50vh - 100px);
  border: 4px double skyblue;
  color: deepskyblue;
  display: flex;
  justify-content:center;
  align-items:center;
}
#B{
  width: 100px;
  height: 50px;
  border: 4px double skyblue;
}
#C{
  width: 100px;
  height: 50px;
  border: 4px double skyblue;
}
```
<font color="mediumvioletred">
``display: flex;``
これでこの**\<div id="A">**タグの**中**は、**フレックスボックス**となります。そして今回、中央寄せにしたいので、

``justify-content:center;``
``align-items:center;``
<font color="mediumvioletred">
と、**水平方向**の設定の**justify-content**と、**垂直方向**の設定の**align-items**を **center**に設定。
![flecen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/8c4b00cb-4298-dae2-12a8-c429dde9a1dc.png)
こうなっていれば**成功**です。:v_tone1:
**フレックスボックス**には並び方の設定がもろもろありますので、こちらの**[チートシート](https://flexbox-cheat.site/)**をみながら色々試してみてください。
## <font color="darksalmon">Grid</font>
<font color="mediumvioletred">
もう一つ、よく使われるのが **グリッド**。今回はレイアウト機能だけちょこっと。
![3colum.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/6984f5fa-9093-1932-b55b-4341715bb1c2.png)
シンプルな３カラムレイアウト。これを**grid**で実装していきます。

``` :html
<body>
  <header>ヘッダー</header>
  <nav>サイドA</nav>
  <main>コンテンツ</main>
  <aside>サイドB</aside>
  <footer>フッター</footer>
</body>
```
``` :css
header{
  border: 4px skyblue double;
}
nav{
  border: 4px skyblue double;
}
main{
  border: 4px skyblue double;
}
aside{
  border: 4px skyblue double;
}
footer{
  border: 4px skyblue double;
}
```
<font color="mediumvioletred">
**N**予備校のプログラミングコースの人には見慣れない**nav**や**aside**タグなどいっぱいですが、全部**\<div>**タグと機能が同じです。見やすくするためにできたタグなので、きにしないでください。
![grilay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/defbad4a-8725-e8c7-df29-9b6261c64394.png)
今回のレイアウトの**親要素はbodyタグ**なので、グリッドの設定は**body**に書いていきます。
<font color="mediumvioletred">
今回記入するのは３つ。まず、bodyをグリットとして設定する
``display: grid;``

グリッドの詳細設定を書き込む
``grid-template``

そして、**子要素**にグリットテンプレートで書いた場所を実際にあてがう
``grid-area``

``` :css
body{
  width: 100vw;
  height: 100vh;
  margin: 0;
  display: grid;
  grid-template:
    "header header header"
    "sideA  main   sideB "
    "footer footer footer"
　　;
}

header{
  grid-area: header;
  border: 4px skyblue double;
}
nav{
  grid-area: sideA;
  border: 4px skyblue double;
}
main{
  grid-area: main;
  border: 4px skyblue double;
}
aside{
  grid-area: sideB;
  border: 4px skyblue double;
}
footer{
  grid-area: footer;
  border: 4px skyblue double;
}
```
ここがグリッドのキモですね。

```  grid-template:
    "header header header"
    "sideA  main   sideB "
    "footer footer footer"
    ;
```
<font color="mediumvioletred">
グリッドのすごさはこの見たまんまのレイアウトできるところ。**ダブルクォート "　"で囲ったところまでが１行**。スペースは**半角スペース**です。**半角ならばどれだけスペース入れても問題ない**ので、見やすく揃えましょう。今回３カラムなので３行。カンマはいりません。**最後にセミコロン**。これだけです。
<font color="mediumvioletred">
で、重要なのは**各子要素**に追記した
``grid-area``
です。ここの値に、グリッドテンプレートに配置した**名前**をあてがっていきます。名前は自由に決めれます。ただ、列（縦)の数は**必ず合わせる必要があります**。ので、仕切りたくない**header**と**footer**は同じ名前をつけて、列の数に合わせます。

![3cgri.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/48a379b0-56ab-2479-2efd-0930300107de.png)
<font color="mediumvioletred">
うまくいったでしょうか？
次に、実際のエリアの大きさの設定です。これもかんたん。

```
  grid-template:
    "header header header" 15vh
    "sideA  main   sideB " 1fr
    "footer footer footer" 15vh
    / 1fr   3fr     1fr
　　;
```
<font color="mediumvioletred">
ただ単に 横に**サイズ**を書き込むだけ。**横の設定は / を入れてから書きます**。今回あえて **fr**という謎単位を使ってますがこれ、**比率**です。今回は　**1fr　 3fr　 1fr　**なので横の長さを **1 : 3 : 1** で割り振っています。この縦の設定の時のような、15vh と 15vh　と固定されたものがある場合、のこりの70vh を比率で割り振ります。ちょーべんり。
![3c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212989/6f9dcc30-dbfd-4004-8285-c5788c504c36.png)
できました？
## <font color="darksalmon">import</font>
<font color="mediumvioletred">
**CSS**は、アプリによっては**膨大**な長さになります。ので、外部ファイルからの**読み込み機能**があったりします。
:green_book: bundle.css
:green_book: A.css
:green_book: B.css
:green_book: C.css
こんな感じにA~Cに分けて書いたCSSを、bundle.cssに一つにまとめて、bundle.cssだけをHTMLファイルに読み込ませたい時につかいます。

``` :bundle.css
@import url("./A.css");
@import url("./B.css");
@import url("./C.css");
```
<font color="mediumvioletred">
@importのカッコの中に、読み込ませたいファイルのパスを入れるだけ。
<font color="mediumvioletred">
:lipstick:　余談
N予備校の冬のWebアプリコンテストでは、応募者全員に、審査する講師陣からアプリのレビューがもらえるのですが、まだこの機能を知らなかった私は、講師陣の皆様全員からすごくソフトに柔らかくやさしく「ファイルを分けてください」という悲痛のレビューをもらってます　:scream:きゃー

ご迷惑おかけしました。
## <font color="darksalmon">変数</font>
<font color="mediumvioletred">
CSSで計算ができるということは、変数も使えたりします。例えば「ボタンはこの色で統一」と、色を変数にしておけば、もし色を変えたい時、変数の色を変えるだけで、すべてのページのボタンの色を変えられたりするので、なかなか便利です。

``` :css
:root {
  --bg-color: blue;
  --main-fontsize: 14px;
}

body{
  background-color: var(--bg-color);
  font-size: var(--main-fontsize);
}
```
``--変数名：値``
<font color="mediumvioletred">
変数の設定方法はこれだけです。( ハイフン(-)２つは必須 )
変数の記入場所のスタンダードは``:root``という擬似クラス。ここは、この変数のスコープ(適用範囲)が、HTML全体になる場所です。
<font color="mediumvioletred">
そして設定した変数の使い方
``var()``
このカッコの中に変数名を書くだけです。Webアプリで大作を作ろうとしてる方は必須かもしれません。

<font color="mediumvioletred">
ではここまでです。レビューする講師陣にやさしいコードを皆でめざしましょう！

:sparkles::christmas_tree:<font color="red"> *Merry Christmas* :christmas_tree::sparkles: