【優しく学べる】CSS in console.log

[CSS Advent Calendar 2019](https://qiita.com/advent-calendar/2019/css) 12日目の記事になります。

# 諸注意
- CSS in console.logはChromeのみ対応となっております。
- CSS in console.logは今後の業務において使う機会は**一切ない**かと思いますので、さらっと読み流すことをおすすめします。(実用的な使い方があったら教えてください)
- 作品だけ見たいよーって人は[応用編](#応用編)まで読み飛ばしてください。

# なぜ書くか
CSSをconsole.logに適用する記事で、しっかりとまめられた記事ってこの世に存在しないんですよね(するわけがない)
てかドキュメントてきなものすらないんですよ。

このままではconsole.logを華やかにしたいって人が困ってしまいますね。
そんな人を助けたいという思いでこの記事を書くに至りました。

# とりあえずやってみる

まずはいつものconsole.log

```js
console.log("We Are CSS");
```


<img width="250" alt="Screen Shot 2019-12-08 at 8.46.04 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/805991a9-56af-e839-b206-bc23b3fcfa12.png">
当然なんの変哲もありません。


スタイルを定義してあげます

```js
const textStyle = "color: teal;";

console.log("We Are CSS");
```
余談ですが、tealはCSSにデフォルトで定義されている色で、「入力のしやすさ」「目への優しさ」「発音のかっこよさ」の全て兼ね備えたCSSカラー界の頂点に君臨する色となっております。
これで普段`red` `blue` `yellow`を背景色に指定して目が痛ぇぇってなっている人に対して一歩差をつけることができますね。

話がそれましたが、定義したスタイルを当てるためにconsole.logを以下のように書き換えます。

```js
const textStyle = "color: teal;";

console.log("%cWe Are CSS", textStyle);
```

<img style="color: red" width="250" alt="Screen Shot 2019-12-08 at 8.42.05 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/ec0b123d-df5a-7866-93f7-332819e1ebc7.png">
するとびっくり、console.logの文字色が変わりましたね。

詳しいことは後ほど説明しますが、
『第二引数にCSSの文字列を渡すと`%c`以降の文字にスタイルが当たるんだな』
ぐらいに思っておいてください。

# 入門編
ということでやってまいりました`css in console.log入門編`
誰が入門するんだって話ですが、書きます。

## 複数のプロパティを使う
先程のスタイルはこうでしたね

```js
const textStyle = "color: teal;";
```

もし複数定義していくと

```js
const textStyle = "color: teal; font-size: 20px; font-weight: bold;"
```

見ての通り、この書き方だとプロパティが横に繋がっていってしまうので可読性めちゃ低いです。
ということで、ここでは配列を使って最後に文字列に直してみましょう。
console.logの部分は変わりません。

```js
const textStyle = [
  "color: teal",
  "font-size: 20px",
  "font-weight: bold",
].join(";");

console.log("%cWe Are CSS", textStyle);
```

<img width="242" alt="Screen Shot 2019-12-09 at 5.55.41 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/e2276ee3-03b3-e1c1-9d0a-9b6ae7d00306.png">


見慣れた形で書くことができ、出力結果もリッチになってきましたね。
そしてだんだんとjs臭が強くなってきましたね(CSSアドベントカレンダーなのにごめんなさい)

## 目的の場所にスタイルをあてる
残念ながらconsole.logにはclassやidといった概念は存在しないので普段使っているセレクタとは異なるアプローチが必要となってきます。

百聞は一見にしかず、見てみましょう。

```js
const tealText = [
  "color: teal",
].join(";");

const plumText = [
  "color: plum",
].join(";");

const peruText = [
  "color: peru",
].join(";");

console.log("%cWe %cAre %cCSS", tealText, plumText, peruText);
```


<img width="250" alt="Screen Shot 2019-12-09 at 5.43.31 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/fc43f756-4ce9-db28-eeb9-4cc8e6bbb6be.png">


なんとなくおわかり頂けるかと思います。
つまり、`%c`から次の`%c`までの要素に対して、第二引数から順番に適用されていきます。

おめでとうございます。入門編突破です。

# 中級編
初級編突破おめでとうございます。
中級編ではconsole.logの落とし穴、デバッグについて触れていきます。

## 全てのプロパティが使えるわけではない

衝撃的ですね。
使えるプロパティはせいぜい20種類ぐらいじゃないかなと思います。

プロパティが対応しているかどうかは以下で紹介する方法で逐一確認をしましょう。

## 出力結果のDOMを確認する
実はChromeにはDeveloper ToolsのDeveloper Toolsというものが存在します。
つまり、こういうことですね。

<img width="526" alt="Screen Shot 2019-12-09 at 6.17.43 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/2b463781-a839-61ec-725e-5e0a6bd8c315.png">

普段見ているDeveloper ToolsもHTML, CSSで作られていることが確認できます。

どうやって見るねんて人はこちらを参考にどうぞ。
[How do you inspect the web inspector in Chrome?](https://stackoverflow.com/a/12291163/11873878)

先ほどのコードを確認してみると
`%c`ごとにspanで区切られ、スタイルがインラインで展開されています。
デバッグは基本的にここで進めていきます。
<img width="249" alt="Screen Shot 2019-12-09 at 6.32.13 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/dc9986ef-c9e7-9f07-cd6f-b2265ce46882.png">

先程も言ったとおり、使えるプロパティはせいぜい20種類です。
`width`, `height`, `display`などなど...
この世界では様々なプロパティが掻き消されます。

ここでは網羅することができないのでご自分の目でお確かめください。

# 上級編
ここからは、この制約の多い中で如何にしてアイデアを形にしていくかのtipsを具体的な例を用いて説明していきます。

## 高さの確保 -> `line-height`
`height`が使えないなら`line-height`
ちなみに、`vh`使えます。
高さの基準はもちろんDeveloper Toolsになります。

```js
const textStyle = [
	"line-height: 100vh"
].join(";");

console.log("%cWe Are CSS", textStyle);
```

無事、存在感のある出力に成功しました。
<img width="701" alt="Screen Shot 2019-12-09 at 7.23.07 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/a21a12c2-bb9f-a774-f249-54bb29b4a3e9.png">

## 中央に寄せたい -> `margin`
中央寄せの定番である`flex`, `position`, `transform`といったプロパティは一切通用しません。
また、`margin: 0 auto;`も機能しません。

ということで、`margin-left`で微調整します。
普段のCSSでは絶対にやってはいけませんね。

```js
const textStyle = [
  "margin-left: 45%",
].join(";");

console.log("%cWe Are CSS!", textStyle);
```

いい感じですね。
<img width="660" alt="Screen Shot 2019-12-09 at 7.50.40 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/afd0dfee-8934-1868-bc65-846ab53e36f8.png">

ちなみに、普段CSSを書いている方なら察しがつくかと思いますが、この書き方、横幅が狭くなると中央寄りではなくなります。

<img width="326" alt="Screen Shot 2019-12-09 at 7.56.43 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/e06f8ea2-483f-ab3d-db00-b41944471052.png">

これを避けるために`margin: 0 45%;`にしたらどうなんだということで、試した結果がこちらです。

残念ながら改行が入ってしまいますね。
ちなみに、改行系のプロパティは`line-break`以外通用しません。
<img width="486" alt="Screen Shot 2019-12-09 at 8.00.01 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/e4b3ad00-5ae8-fea4-f498-ed2894598b23.png">

ここでは完璧な中央寄せを見つけることができませんでした。
良い中央寄せの解決策をお持ちの方がいましたら、ぜひ共有よろしくお願いします。


## 画像を表示 -> `background-image`
imageタグは使えないので`background-image`で対応します。
このへんはいつも通りで大丈夫ですが、強いていうならば`padding`でサイズを確保してあげないといけません。

```js
const imageStyle = [
  "padding: 200px",
  "background-image: url(https://media.giphy.com/media/VbnUQpnihPSIgIXuZv/giphy.gif)",
  "background-repeat: no-repeat"
].join(";");

console.log("%c ", imageStyle);
```
<img width="620" alt="Screen Shot 2019-12-11 at 6.27.51 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/3ebffedb-0bd5-93ac-1206-ad77b418ee45.png">

## ダークモードに対応 -> `matchMedia`
ごめんなさいめっちゃJSです。
`matchMedia`を使うとCSSのMedia Queriesの役割が果たせるのでこれで`prefers-color-scheme`を呼んであげればいいですね。

```js
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

const textStyle = [
  `color: ${isDark ? "white" : "black"}`,
  "font-size: 30px",
  "font-weight: bold",
].join(";");

console.log("%cCan you read me?", textStyle);
```

<img width="752" alt="Screen Shot 2019-12-11 at 7.27.58 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/baa1048f-0f71-1a9a-4d7d-3be99804f6ae.png">
<img width="756" alt="Screen Shot 2019-12-11 at 7.27.05 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/81e9b69b-dffa-56a5-2658-b1f104465459.png">

ということで上級編は無駄なtipsを紹介いたしました。
ほかにもこういう裏ワザあるよーって方がいましたらお待ちしております。


# 応用編

ここからはソースコードを交えつつ作品を紹介していきます。
一応CODEPEN貼っておきますが、CODEPENのページにアクセスしてからconsoleを開かないと見れないので肉眼で確かめたい人のみお使いください(ほとんどの環境でうまく動作する気がしませんが)


## ポケモンスライドショー
まずは画像から
最近10年ぶりにポケモンを始めてめちゃくちゃハマってます
みなさんまだ気づいていないようですが、**ウッウが恐ろしく強い**です。

![Dec-11-2019 18-51-55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/11140b02-a18c-969c-6707-0ae28b6abaa3.gif)


<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="mo-ro" data-slug-hash="YzPybwb" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="YzPybwb">
  <span>See the Pen <a href="https://codepen.io/mo-ro/pen/YzPybwb">
  YzPybwb</a> by Kotaro (<a href="https://codepen.io/mo-ro">@mo-ro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## text-shadowアート

次は`text-shadow`軸でやっていきます。
おまえ使えるんかい。感がすごい。
ちなみに`box-shadow`は使えないです。

`text-shadow`もちゃんと使えば
こうなります。
<img width="639" alt="Screen Shot 2019-12-10 at 5.53.48 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/70f05758-1294-80f9-fe3e-e41e139efc4e.png">

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="mo-ro" data-slug-hash="YzPqvWJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="We Are CSS!">
  <span>See the Pen <a href="https://codepen.io/mo-ro/pen/YzPqvWJ">
  We Are CSS!</a> by Kotaro (<a href="https://codepen.io/mo-ro">@mo-ro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


もうちょっと頑張れば
こうなりますね。

<img width="639" alt="Screen Shot 2019-12-10 at 5.48.07 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/26b1d824-535b-d97a-8a17-005223682c7d.png">

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="mo-ro" data-slug-hash="BayKVmy" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Colorful Bar">
  <span>See the Pen <a href="https://codepen.io/mo-ro/pen/BayKVmy">
  Colorful Bar</a> by Kotaro (<a href="https://codepen.io/mo-ro">@mo-ro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## メリークリスマス
今年もメリークリスマスが近づいてきましたね。
せっかくなので紹介した技術を使ってクリスマス的な何かを表現したいなと思い作りました。

**完成**
<img width="429" alt="Screen Shot 2019-12-10 at 9.31.17 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125293/569f772c-1214-6f0d-cd43-827b16c04bc7.png">

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="mo-ro" data-slug-hash="wvBGXjK" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="wvBGXjK">
  <span>See the Pen <a href="https://codepen.io/mo-ro/pen/wvBGXjK">
  wvBGXjK</a> by Kotaro (<a href="https://codepen.io/mo-ro">@mo-ro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

まじできつかった。
この記述量で2日ぐらいかかりました。。。

特にきつかったのが、こいつら強制的に`inline-block`になる上にwidthが指定できないのでもちろん全部横並びになるんですよね。
なので`\n`で改行を挟んで無理やり縦並びにしたところ、(多分)バグで一つ前に定義したスタイルが複製されてしましました。

もしconsole.log芸に取り組む方がいましたら改行を使わない実装を心がけることをおすすめします。

# おわりに
こういうことQiitaでやると批判受けそうです怖いんですが、
現在、インターン・就職先大募集中でございます。
console.logを美しくしたいなあって企業がありましたらご連絡お待ちしております。