【HTML/CSS】Udemyコースで学んだ良い感じなデザインの共通点をまとめてみる

## この記事は何？

Udemyで**20 Web Projects With Vanilla JavaScript**というコースを受講しました。

https://www.udemy.com/course/web-projects-with-vanilla-javascript

HTML/CSS/VanillaJSで良い感じなデザインのアプリを20個作っていく、フロントエンド初学者向けのコースです。

コースを進めていく中で、デザインに**共通点が多い**事に気が付きました。

そこで、今後の自分のためにこのコースで登場するデザインの共通点をまとめることにしました。

### 受講の動機

HTML/CSS/JavaScriptで10個(くらい)何かを作ってみるチャレンジの一環として受講しました。

何か作ってみるチャレンジの目的は、**HTML/CSS/Vanilla JSを使ってとりあえずなにか作ること、手を動かすこと**です。

プログラミングにおいて手を動かすに勝る学習方法はないと思います。
実感としてもそうですし、そう言っているエンジニアの方も多くいます。
また、質を高めるためにも、まずは絶対的な量が必要とよく言います。

というわけで、色々作ってみることにしました。

しかしその中で、文法はある程度わかっていても**サイトのデザインやレイアウトをどのように考え・作っていけば良いのか全くと言っていいほどわからない**ことに気が付きました。

そこで、まずは良いデザインとはどういったものなのか？を学びつつ、手を動かせる教材を選びました。

***

チャレンジのリポジトリ

https://github.com/NasuPanda/frontend-practices

***

### 注意点

- 初心者向けの記事です。
  - そんなの常識やん、という内容が多々含まれる恐れがあります。
- 細心の注意を払ってはいますが、勘違い・ミスがあるかもしれません。見つけたらそっと指摘していただけると幸いです。
- 「この方法が最適解！」というわけではないです。

## 本題の前に

### VSCodeのTips

いくつか講座内で紹介されていたVSCodeのTipsを紹介します。

#### 拡張機能 Auto Rename Tag

https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag

ペアになっているタグを自動でリネームしてくれる拡張機能です。
普通に便利。

#### 拡張機能 Lite Server

https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer

VSCode限定というわけではありませんが、VSCodeなら簡単に拡張機能として利用可能なので紹介します。
**ファイルの変更を監視・ブラウザに反映してくれる**軽量なローカルWebサーバです。

- [BrowserSync](https://zenn.dev/yuki0410/articles/8ee3433cfa5b807968d0-2)をSPAに対応出来るようにしたラッパーです。
- HTML/CSS/JSファイルの変更を監視、変更されたら即ブラウザに反映してくれます。
- Liteというだけあって、ロードが超早いです。

拡張機能の検索欄で「Lite Server」と検索、インストールするだけで導入できます。

#### HTMLの入力

VSCodeでHTMLを書くときは下の表のように入力すると効率良く入力出来ます。

| 入力 | 結果 |
| --- | --- |
| .active | `<div class="active"></div>` |
| タグ.class-name#id-name | `<タグ class="class-name" id="id-name"></タグ>` |

![vscode-html](https://user-images.githubusercontent.com/85564407/156861755-372ff8f3-2933-44e7-b51e-5ff054f831bd.gif)

### Google Fontの利用

[Browse Fonts - Google Fonts](https://fonts.google.com/)から好きなフォントを選んで導入します。

今回はCSSの`@import`により利用します。

```css
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@100&family=Roboto:wght@100&display=swap');
```

導入の参考になりそうな記事

- [Google Fonts を使ってみよう - Qiita](https://qiita.com/eimy9/items/2fdedf840cb551cc83c2)
- [Rails Googleフォント 使い方（初心者） - Qiita](https://qiita.com/iggy-neko/items/b20babb7bf7f5f61ce4e)

### Font Awesomeの利用

[Font Awesome](https://fontawesome.com/)から好きなアイコンを選んで導入します。

`head`に`link`を追加して利用出来るようにします。

```html
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/all.min.css" rel="stylesheet">
```

HTMLで下のように書くだけでアイコンが表示されます!
無料プランだと使用できるアイコンに制限があるようです。

```html
<i class="fas fa-search"></i>
<i class="fas fa-random"></i>
```

導入の参考になりそうな記事

- [Font Awesomeの使い方 - Qiita](https://qiita.com/momo1010/items/0374fb7f0b1d465384b4)

### CSSセレクタ

動画内で多用されていた基本的なセレクタについておさらいします。
実際使うときはネストが深くなりすぎないように注意。

```html
<ul class="showcase">
    <li>
        <div class="seat"></div>
        <small>N/A</small>
    </li>
    <li>
        <div class="seat selected"></div>
        <small>Selected</small>
    </li>
    <li>
        <div class="seat occupied"></div>
        <small>Occupied</small>
    </li>
</ul>
```

```css
.seat.selected {
    background-color: #6feaf6;
}
```

`.seat` と `.selected` を持つ要素が選択される

```css
.seat:not(.occupied):hover {
    cursor: pointer;
    transform: scale(1.2);
}
```

`.seat` の内、 `.occupied` を持たない要素が選択される

```css
.showcase .seat:not(.occupied):hover {
    cursor: default;
    transform: scale(1);
}
```

`.showcase` の子要素、かつ `.seat` を持ち、 `.occupied` を持たない要素が選択される

## 本題

前置きが長くなりましたが、本題に入っていきます。

### 例として見ていくレイアウト

- [映画の座席予約アプリ](https://github.com/bradtraversy/vanillawebprojects/tree/master/movie-seat-booking)

![movie-seat-bokking.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/b922c742-34c5-4b31-8839-7d7f85f1cba3.png)

- [レシピ検索アプリ](https://github.com/bradtraversy/vanillawebprojects/tree/master/meal-finder)

![meal-finder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/db22ea42-0e8c-fe05-9d94-74055ac1d5e7.png)

- [収支管理アプリ](https://github.com/bradtraversy/vanillawebprojects/tree/master/expense-tracker)

![expense-tracker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/20715c5d-bf95-ae23-2284-cf815bb7a652.png)

- [フィード閲覧アプリ](https://github.com/bradtraversy/vanillawebprojects/tree/master/infinite_scroll_blog)

![Infinite-scroll.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/e31be74b-54c9-9482-adcb-75a96b90a598.png)

- [ニューイヤーカウントダウン](https://github.com/bradtraversy/vanillawebprojects/tree/master/new-year-countdown)

![New-Year.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/125204d5-cea2-4224-582a-3e1503903731.png)

詳細は講師の方のリポジトリを参照してください。

https://github.com/bradtraversy/vanillawebprojects

### 要素内に余白を作りたいときは`padding`を使う

要素内に適度な余白を作りたい時には`padding`を使います。
中にテキストを持つ要素はほとんど`padding`を使っていました。

**`padding`あり**
![padding.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/f9ceb811-346e-64ab-cae9-49307fa18c35.png)
**`padding`なし**
![non-padding.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/f517d09a-8130-0ae2-59b6-d850cafd1a89.png)

**`padding`あり**
![padding-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/37e03f26-6d8d-06dd-35b1-c3c642915067.png)
**`padding`なし**
![non-padding-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/4ea2be85-bc84-9f06-2c6a-bbc621931402.png)

**`padding`あり**
![padding-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/f3751f38-0f59-465f-3fa9-3cc34383c0ed.png)
**`padding`なし**
![non-padding-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/5d175f37-6f9b-8bd9-e50c-8602ccbe8c61.png)

`padding`ありの方が圧倒的に良いですね。

### 要素間を離したい時は`margin`

当然といえば当然ですが、要素サイズの大小に関わらず要素間の距離を開けたい時は`margin`を上手く使います。

![margin-big.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/083bef8c-2b05-708d-e7c3-958b6cddc512.png)
![margin-medium.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/35f8d8a1-a0e1-256a-d418-a9b94498c214.png)

大きな`margin`よりも、小さい要素間の距離を少し開けたい時に使う`margin`の方が難しく感じました。
![margin-left.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/54852be2-7c07-60bf-3c48-8dbe45ef2427.png)
![margin-small.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/fee76f97-8446-37eb-901b-77741e7f36dc.png)

詳しくは後述しますが、N番目の要素にのみ`margin`を適用することで映画館の座席っぽいデザインを作ることが出来ます。

![movie-seats.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/97486cdc-88ca-1d3c-daaa-04ddad94c0c3.png)

### レイアウトの構成

レイアウト構成については、この教材の場合`flex`の使用率が圧倒的でした。

レイアウト全体をいくつかの大きめな「ブロック」に分割して構成、`body`に`flex`を適用して中央寄せ。
という流れが多かったです。

![felx-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/dafd4710-d480-beef-5095-727e4ccd457b.png)
![flex-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/b9196648-a02f-0547-f7e9-b5408cfa0d35.png)
![flex-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/f390d7e2-293c-4d66-5998-04db710edb9a.png)
![flex-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/934a46c5-fa62-687b-1dd7-8f5a675f5fbe.png)

この流れでレイアウトを組んでいくと全体の構成がつかみやすく、どのように全体のレイアウトを組んでいけば良いのかわかりやすかったです。
また、勝手に中央寄せになってくれるので全体的にスッキリします。

### `border-radius`をよく使う

指定した長さを半径として、ブロックの四隅を丸くするプロパティです。

カクカクしたデザインよりも少し角を丸めたデザインが多かった印象です。

**`border-radius`あり**
![border-radius.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/87607fc2-5164-4c62-fae1-5fde045adc32.png)
**`border-radius`なし**
![border-radius-none.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/48cbe21a-977d-751e-8bc7-911ca0cabd80.png)
**`border-radius`あり**
![border-radius-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/7fb05c63-e91f-d2f0-2f79-f982d534a876.png)
**`border-radius`なし**
![bouder-radius-none-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/93f24840-9181-9c42-4e19-e5c777d408ed.png)

また、`border-radius`というより`border`の使い方になりますが、下のように画像を`border`で囲んでいます。
ただ画像を表示するよりもよりカードっぽく表示することが出来ます。
![images-good.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/586b393b-427d-df93-1cb5-3b02de4541e2.png)

### 1番上/下の要素は上/下に余白を作る

1番上/下にいる要素は上/下に`margin`を設定することで、不自然に上下に寄らない程度の余白を作っていました。

![margin-top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/0c6860ed-2e8a-8896-c761-e008c757e3b4.png)
![margin-top-buttom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/569cc56b-7f1c-fd17-ac18-0b126995dff5.png)

### 開発の流れ

JavaScriptによるDOM操作でレイアウトを作る場合、以下の流れが共通していました。
「チュートリアルでやるような小規模なアプリケーションだとこの方がわかりやすい」という話かもしれませんが、実際この流れだと理解しやすかったです。

1. まずダミーHTML（JavaScriptで作る予定のレイアウト）を書く
2. ダミーHTMLに対してCSSを書いてスタイルを設定
3. 最後にJavaScriptを書き、DOM操作でレイアウトを作っていく

## 使えそうなデザイン達

何かしら使えそうなデザイン達をまとめていきます。

### 映画館の座席っぽく

![movie-seat](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/bdc5e546-e137-4d1c-0d01-97fff5201a6d.png)

```html
<div class="row">
  <div class="seat"></div>
  <div class="seat"></div>
  <div class="seat"></div>
  <div class="seat occupied"></div>
  <div class="seat occupied"></div>
  <div class="seat"></div>
  <div class="seat"></div>
  <div class="seat"></div>
</div>
```

```css
.row {
    display: flex;
}
.seat {
    background-color: #444451;
    height: 12px;
    width: 15px;
    /* 要素を切り離す */
    margin: 3px;
    /* 左右上側を丸めてシートっぽくする */
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}
```

四角を作る → `margin`で切り離す → 左右上側を丸める
ことで作ることができます。

#### N番目の子要素を選択

映画館の座席なので、下のように端2列は中心4列から少し離したいです。

![movie-seat-2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/3f85db5c-af7f-0d7c-47d6-50a3c8edd358.png)

そこで、 `nth-of-type`を使います。

```css
.seat:nth-of-type(2) {
    margin-right: 18px
}

.seat:nth-last-of-type(2) {
    margin-left: 18px
}
```

**参考**

- [:nth-child() - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/:nth-child)
- [:nth-of-type() - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/:nth-of-type)
- [【CSS】nth-childとnth-of-typeでもう混乱しない。 - Qiita](https://qiita.com/shunsuke227ono/items/6c9916f80d82b73a7025)

**`:nth-of-type()`**
**「指定した要素の親要素」の子要素**のうち、**指定したセレクタ**の「N番目」の要素を選択する。

**`:nth-child()`**
**「指定した要素の親要素」の子要素**を見て、**セレクタ関係なし**に「N番目」の要素を選択する。

#### カーソルされた時に強調

![movie-seat-cursole](https://user-images.githubusercontent.com/85564407/156902070-040b1ec9-077d-42a1-bfe3-c7735bf57bd5.gif)

```css
.seat:not(.occupied):hover {
    cursor: pointer;
    transform: scale(1.2);
}
```

### 立体的なスクリーン

```css
.screen {
    background-color: #fff;
    height: 70px;
    width: 100%;
    margin: 15px 0;
    transform: rotateX(-45deg);
    box-shadow: 0 3px 10px rgba(255, 255, 255, 0.7);
}
.container {
        perspective: 1000px;
        margin-bottom: 30px;
    }
```

`transform` でX軸を基準に-45度回転させ、
`perspective` で3D配置された子要素に遠近感を与えます。

- [CSS perspectiveを使ったデザイン - Qiita](https://qiita.com/junya/items/a456e14da4bb2b11806f)
    
回転・遠近なし
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/175e36e5-db49-62ba-9956-e84d215f6930.png)

回転・遠近あり
X軸を基準に若干傾き、3D風になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/21279bfe-b544-88e4-73ef-2256b3bca7b2.png)

### 検索欄

```html
<div class="flex">
    <form class="flex" id="submit">
        <input type="text" id="search" placeholder="Search for meals or keywords">
        <button class="search-btn" id="submit" type="submit">
            <i class="fas fa-search"></i>
        </button>
    </form>
    <button class="random-btn" id="random">
        <i class="fas fa-random"></i>
    </button>
</div>
```

完成形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/d85416b4-f782-8d39-bc0c-92150fbb37bb.png)

***

```css
.flex {
    display: flex;
}

input,
button {
    border: 1px solid #dedede;
    border-top-left-radius: 4px;
    border-bottom-left-radius: 4px;
    font-size: 14px;
    padding: 8px 10px;
    margin: 0;
}

input[type="text"] {
    width: 300px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/5c8d140f-69ae-4543-7295-b5d1c03de596.png)
- `input` 、2つの `button` を `.flex` で囲って横並びに
- 共通で`border` をセット、左側の角を丸める

***

```css
.search-btn {
    cursor: pointer;
    border-left: 0;
    border-radius: 0;
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/054e2126-d5a3-19a1-69a2-ca3c8fdebb80.png)

- `.search-btn` の `border` を削除、右側だけ丸める

***

```css
.random-btn {
    cursor: pointer;
    margin-left: 10px;
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/d78ffaa8-ad96-f26b-3b78-a629f2645c9d.png)

- `random-btn` は検索欄から少しだけ離し、右側も丸める。共通で左側を丸めてあるので、両側が丸められる。

### 画像をカード風に表示する

```html
<div id="meals" class="meals">
    <div class="meal">
        <img src="https://www.themealdb.com/images/media/meals/ysxwuq1487323065.jpg" alt="Fish pie">
        <div class="meal-info" data-mealid="52802">
            <h3>Fish pie</h3>
        </div>
    </div>

    <div class="meal">
        <img src="https://www.themealdb.com/images/media/meals/a15wsa1614349126.jpg" alt="Fish fofos">
        <div class="meal-info" data-mealid="53043">
            <h3>Fish fofos</h3>
        </div>
    </div>
</div>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/4f7e96e4-8b4e-17a3-cd5d-c84fbe0a7559.png)

```css
.meals {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    /* grid 同士の距離 */
    grid-gap: 20px;
    margin-top: 20px;
}
```

- `grid` で4列表示にして間隔を離す。

```css
.meal {
    cursor: pointer;
    position: relative;
    height: 180px;
    width: 180px;
    text-align: center;
}
```

- 元画像のサイズで表示されないようにサイズに制限をかける
- `absolute`を子要素で利用するため、 `relative` にしておく

```css
.meal img {
    width: 100%;
    height: 100%;
    border: 4px #fff solid;
    border-radius: 2px;
}
```

- 画像の周りをボーダーで囲って丸める　→　画像オンリーよりもカードっぽく
- 幅と高さを親要素 `meal` に対する100％に

```css
.meal-info {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.2s ease-in;
    opacity: 0;
}

.meal:hover .meal-info {
    opacity: 1;
}
```

`meal` > `img` & `meal-info`なので、 `meal-info` は本来画像の下側に表示される。

今回はホバーしたら `meal-info` が表示される形にしたいので、 `absolute` を使って親要素の真上に `meal-info` を持ってくる。

そして、ホバーされた時に `opacity` が1になるようにする。

![hover](https://user-images.githubusercontent.com/85564407/155867516-428571b2-8194-45f4-af49-6527ee0b8991.gif)

#### メディアクエリ

```css
@media(max-width: 800px) {
    .meals {
        grid-template-columns: repeat(3, 1fr);
    }
}
@media(max-width: 700px) {
    .meals {
        grid-template-columns: repeat(2, 1fr);
    }

    .meal {
        height: 200px;
        width: 200px;
    }
}
@media(max-width: 500px) {
    input[type="text"] {
        width: 100%;
    }
    .meals {
        grid-template-columns: repeat(1fr);
    }
    .meal {
        height: 300px;
        width: 300px;
    }
}
```

幅に応じて `grid` 、 `meal` の幅を変更することでレスポンシブに。

### 材料の一覧表示（整列されていないリスト）

`display`をいじってあえて整列していないリストにすることで、一覧性を高める事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/de36b852-bd10-62b3-8455-6d58a73f6327.png)

```css
ul {
    padding-left: 0;
    list-style-type: none;
}

ul li {
    border: 1px solid #dedede;
    border-radius: 5px;
    background-color: #fff;
    display: inline-block;
    color: #2d2013;
    font-size: 12px;
    font-weight: bold;
    padding: 5px;
    margin: 0 5px 5px 0;
}
```

### 2つの横並び要素をそれぞれの中央に配置

完成形
![income-expense.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/c2e57608-0460-c680-146a-bd993ecad0d7.png)

***

INCOMEとEXPENSEをそれぞれ中央に配置したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/c51fba83-ef6b-211b-a84f-b3563744569f.png)

```html
<div class="inc-exp-container">
    <div>
        <h4>Income</h4>
        <p id="money-plus" class="money plus">+$0.00</p>
    </div>
    <div>
        <h4>Expense</h4>
        <p id="money-minus" class="money minus">-$0.00</p>
    </div>
</div>
```

```css
.inc-exp-container {
    background-color: #fff;
    box-shadow: var(--box-shadow); /* 変数を利用 */
    padding: 20px;
    display: flex;
    justify-content: space-between;
}
```

`flex` + `space-between` でコンテナの両サイドに表示。

***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/116af72d-1e9e-b2ca-e7e9-2c098b5c82f7.png)

```css
.inc-exp-container div {
    flex: 1;
    text-align: center;
}

.inc-exp-container div:first-of-type {
    border-right: 1px solid #dedede;
}
```

`flex: 1` で隙間を埋めることで中央寄せする。

`flex: 1;`は一括指定プロパティ。
値が一つの場合は `grow` (空いた幅を埋める)を設定したことになる。

- [flex-grow](https://developer.mozilla.org/ja/docs/Web/CSS/flex-grow)
- [flex-shrink](https://developer.mozilla.org/ja/docs/Web/CSS/flex-shrink)
- [flex-basis](https://developer.mozilla.org/ja/docs/Web/CSS/flex-basis)

### ホバーすると表示される削除ボタン

![hover-delete](https://user-images.githubusercontent.com/85564407/156902719-f525bdb2-cc66-4018-9a7c-2550b9011c9f.gif)

```css
.delete-btn {
    cursor: pointer;
    background-color: #e74c3c;
    border: 0;
    color: #fff;
    font-size: 20px;
    line-height: 20px;
    padding: 2px 5px;
    position: absolute;
    top: 50%;
    left: 0;
    transform: translate(-100%, -50%);
    transition: opacity 0.3s ease;
    opacity: 0;
}

.list li:hover .delete-btn {
    opacity: 1;
}
```

`transform: translate(-100%, -50%);`でXY位置を調整している。

### 丸数字を表示

![circle-number.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/c5468442-cb2f-5eee-22dc-712a0acce4ef.png)

```html
<div class="post">
  <div class="number">1</div>
  <div class="post-info">
    <h2 class="post-title">sunt aut facere repellat provident occaecati excepturi optio reprehenderit</h2>
    <p class="post-body">quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto</p>
  </div>
</div>
```

```css
.number {
    position: absolute;
    top: -15px;
    left: -15px;
    font-size: 15px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #fff;
    color: #296ca8;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 7px 10px;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/09b29a2e-b42e-c874-8e16-661987e6e995.png)
`post` に対して `absolute` + `-15px` → 左上に固定
`flex` で中央寄せ → `number`の中身を中央に寄せる

### 丸がバウンドするアニメーション

![bounce-animation](https://user-images.githubusercontent.com/85564407/156571215-e1a51e7b-4aa4-4e7c-b0f6-43c523b79c55.gif)

```css
.circle {
    background-color: #fff;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin: 5px;
    animation: bounce 0.5s ease-in infinite;
}

.circle:nth-of-type(2) {
    animation-delay: 0.1s;
}

.circle:nth-of-type(3) {
    animation-delay: 0.2s;
}

@keyframes bounce {
    0%,
    100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-10px);
    }
}
```

丸を作る → アニメーションを設定 → ディレイを入れるだけです。

### 背景を画像にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/101d5ad1-e816-9748-74f4-fa900694dbd3.png)

```css
body {
  background-image: url('https://images.unsplash.com/photo-1467810563316-b5476525c0f9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80');
  /* 背景画像を1枚のみにする */
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
  height: 100vh;
  color: #fff;
  font-family: "Lato", sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: 0;
  overflow: hidden;
}
```

#### 背景画像を暗くする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/ce2d36e7-d192-2920-e943-720382731383.png)

```css
body::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}
```

疑似要素に対して `background-color` を割り当てることで暗くします。

文字まで暗くなってしまっているので修正します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1224564/c211fbc9-1df6-6218-7c7c-c27d3979c4c1.png)

```css
body * {
  z-index: 1;
}
```

`z-index` の指定により背景以外が暗くならないようにします。

## まとめ

- 余白は大事！！
    - `padding`と`margin`を上手く使う
    - 最初はパクるところから
- 最初にざっくり全体のレイアウトを決めてしまうと楽。
- よく使うデザインの早引き的なものがあると良さげ。