CSS について深い知識はないけどこれだけ知ってれば何とかなるでしょ、的な雑記帳

CSS が苦手です。border とか margin とかちょろちょろっと触るだけならできますけど、最近の新しいやつはほとんど知りません。とはいえフロントエンド畑にいると、CSS フレームワークを使わずに自力で CSS 書いて見た目を調整する事とか、ありますよね（管理画面系とか）。

CSS について深い知識はないけどこれだけ知ってれば何とかなるでしょ、的な雑記帳としてメモを残しておこうと思います。

# Layout

## flex で水平/垂直方向の配置

`justify-content` | `align-items` | プレビュー | Playground
--- | --- | --- | ---
`flex-start` | `center` | <img width="400" src="https://user-images.githubusercontent.com/15980747/101229588-4b60a380-36e4-11eb-8f9f-3a926808a7b3.png"> | [liveweave](https://liveweave.com/c4PX03)
`center` | `center` | <img width="400" src="https://user-images.githubusercontent.com/15980747/101229590-4c91d080-36e4-11eb-89af-438a95e74f3f.png"> | [liveweave](https://liveweave.com/I5BxR9)
`flex-end` | `center` | <img width="400" src="https://user-images.githubusercontent.com/15980747/101229591-4d2a6700-36e4-11eb-961c-7bf96b6a9487.png"> | [liveweave](https://liveweave.com/fRfquf)
`flex-start` | `flex-start` | <img width="400" src="https://user-images.githubusercontent.com/15980747/101229592-4dc2fd80-36e4-11eb-83f4-f97aafd49ea6.png"> | [liveweave](https://liveweave.com/KIjwQr)
`flex-start` | `flex-end` | <img width="400" src="https://user-images.githubusercontent.com/15980747/101229593-4e5b9400-36e4-11eb-998d-a37b10c1c430.png"> | [liveweave](https://liveweave.com/sza8rs)

TL;DR
- `flex-direction: row` で　１行にコンテンツ配置
- `justify-content` で水平方向の指定
- `align-items` で垂直方向の指定

```html
<div>
  <p></p>
  <p></p>
  <span></span>
  <input placeholder="input"/>
  <button>button</button>
</div>
```

```css
/* コンテナ */
div {
  display: flex;
  flex-direction: row;
  /* justify-content: flex-start | center | flex-end; */
  /* align-items: flex-start | center | flex-end; */
}

/* 子要素間の左右マージン */
/* `*` が遅いらしいので実際使う時は button,p などに変更 */
div > * {
  margin: 0 0.3em;
}
```

## 横並びグリッドレイアウト

<img width="500px" src="https://user-images.githubusercontent.com/15980747/100703471-ec9ae180-33e6-11eb-896c-144d4a527275.gif">

https://liveweave.com/XiBLlR

TL;DR
- `grid-template-columns: repeat(3, 30%)`　で 30 %幅の列を 3 個作る
- `grid-template-columns: 100px 90px 80px` とすれば列ごと個別の幅指定も可
- `grid-template-rows` とすれば列でなく行で同じ事ができる

```html
<div>
  <article><img src="https://picsum.photos/id/237/200/300"/></article>
  <article><img src="https://picsum.photos/id/1025/200/300"/></article>
  <article><img src="https://picsum.photos/id/1062/200/300"/></article>
</div>
```

```css
div {
  display: grid;
  grid-template-columns: repeat(3, 30%);
  grid-gap: 3%;
}
```

# Utility

## ブロック要素をドラッグ＆ドロップでリサイズ可能に

<img width="400px" src="https://user-images.githubusercontent.com/15980747/100681750-c90c7280-33b7-11eb-95bc-aff3b337ccc1.gif">

https://liveweave.com/ZdsRON

TL;DR
- `resize` でリサイズ可能になる

```html
  <header>
    <div>contents</div>
    <div>contents</div>
    <div class="resizable-h">resizable-h</div>
  </header>
  
  <nav class="resizable-v">resizable-v</nav>
```

```css
.resizable-h {
  min-width: 10em;
  overflow: hidden; /* これがないとリサイズ効かない */
  resize: horizontal; /* 横方向のリサイズ */
  background: #516f8d;
}

.resizable-v {
  min-height: 10em;
  overflow: hidden; /* これがないとリサイズ効かない */
  resize: vertical; /* 縦方向のリサイズ */
  background: #516f8d;
}
```

## dl>ddの空要素にハイフンをデフォルト表示

<img width="400px" src="https://user-images.githubusercontent.com/15980747/100732473-174d6000-3410-11eb-863d-caacfecd41cb.png">

https://liveweave.com/3lBwTm

TL;DR
- `dd:empty` で空要素の判定ができる

```html
<dl>
  <dt>Artist</dt>
  <dd>Queen</dd>
  <dt>Title</dt>
  <dd>Made in Heaven</dd>
  <dt>Release date</dt>
  <dd></dd> <!-- 空要素 -->
  <dt>Review</dt>
  <dd>this is the best Album</dd>
</dl>
```

```css
dd:empty::before {
  content: '-';
}
```

## フォーカスした時にバリデーションエラー表示

<img width="400px" src="https://user-images.githubusercontent.com/15980747/100699430-4945ce80-33de-11eb-9c48-5f18cedd0132.gif">

https://liveweave.com/yrDXFO

TL;DR
- `focus-within` を使えば div タグに「子要素がフォーカスを持っている時」の CSS を書ける
- `focus-visible` でフォーカスリングを消す
- `caret-color` でキャレットの色を変更

```html
<!-- FontAwesome 使用 -->
<div>
  <i class="fa fa-user"></i>
  <input type="text">
</div>
```

```css
input {
  caret-color: red;
}

/* 子要素がフォーカスを持つ時に適用される CSS */
div:focus-within i {
  color: #f56161;
}
div:focus-within input {
  border: 1px solid #f56161;
}

/* 影つけて強調 */
input:focus {
  box-shadow: 2px 2px 2px 0 #f56161;
}

/* フォーカスリングを消す */
input:focus-visible {
  outline: none;
}
```

## ライブラリ使わないフワッと出るダイアログ

<img width="500px" src="https://user-images.githubusercontent.com/15980747/100710418-06422600-33f3-11eb-9351-d2550a1c9cf3.gif">

https://liveweave.com/Ba3UZZ

TL;DR
- `<dialog>` 設置
- `document.getElementById("id").showModal()` でダイアログオープン
- CSS で `transition` を使えばフワッと感を出せる

```html
<dialog id="dialog">
  <!-- form がないとボタンが反応しないので必須 -->
  <form method="dialog">
    <p>これ便利じゃないですか?</p>
    
    <!-- button の value が dialog.returnValue になる -->
    <button value="yes">yes</button>
    <button value="no">no</button>
  </form>
</dialog>

<button id="trigger">Open dialog</button>
```

```js
const $trigger = document.getElementById("trigger");
const $dialog = document.getElementById("dialog");

$trigger.addEventListener("click", () => {
  $dialog.showModal();
});

$dialog.addEventListener("close", () => {
  $result.value = $dialog.returnValue;
});
```

```css
dialog {
  /* opacity 効かせるために display 必須 */
  display: block;
  opacity: 0;
}

dialog[open] {
  /* 2秒間かけて opacity を 0 > 1 に変化させる（フワッ） */
  opacity: 1;
  transition-property: opacity;
  transition-duration: 2s;
  transition-timing-function: ease;
}
```