アンパンマンをcssで描く

cssで初めてキャラクターを制作したので、その時に行ったことについて紹介します。

# 制作物

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

# 全体のコード

```html
<!-- 顔 -->
<div class="face">
  <!-- 眉毛 -->
  <div class="eyebrowsWrapper">
    <div class="eyebrows eyebrows--left"></div>
    <div class="eyebrows eyebrows--right"></div>
  </div>
  <!-- 目 -->
  <div class="eyeWrapper">
    <div class="eye eye--left"></div>
    <div class="eye eye--right"></div>
  </div>
  <!-- 鼻・頬 -->
  <div class="noseWrapper">
    <div class="nose nose--left"></div>
    <div class="nose nose--center"></div>
    <div class="nose nose--right"></div>
  </div>
  <!-- 口 -->
  <div class="mouse"></div>
</div>
```

```scss
// reset
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  &::before,
  &::after {
    box-sizing: border-box;
  }
}

// 要素自体を中央に
body {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  min-height: 300px;
}

// 顔
.face {
  position: relative;
  width: 300px;
  height: 300px;
  border: 3px solid #000;
  border-radius: 50%;
  background: #fe935d;
}

// 眉毛
.eyebrowsWrapper {
  display: flex;
  justify-content: space-between;
  width: 190px;
  height: 50px;
  margin: 50px auto 0;
}

.eyebrows {
  width: 70px;
  height: 50px;
  border-radius: 50px 50px 0 0;
  border-top: 3px solid #000;
  border-right: 3px solid #000;
  border-left: 3px solid #000;
  &--left {
    left: 0;
  }
  &--right {
    right: 0;
  }
}

// 目
.eyeWrapper {
  display: flex;
  justify-content: space-between;
  width: 160px;
  height: 54px;
  margin: -25px auto 0;
  background: #ff0;
}

.eye {
  width: 40px;
  height: 50px;
  background: #000;
  border-radius: 50%;
}

// 鼻
.noseWrapper {
  display: flex;
  justify-content: center;
}

.nose {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  &::before {
    content: '';
    display: block;
    width: 60%;
    height: 100%;
  }
  &::after {
    content: '';
    position: absolute;
    top: calc(50% - 6px);
    left: calc(50% - 6px);
    display: block;
    width: 12px;
    height: 12px;
    background: #fff;
  }
  &--left {
    margin-top: 5px;
    margin-right: -5px;
    background: #fe523c;
    &::before {
      margin-left: auto;
      border-radius: 0 80px 80px 0;
      border-top: 3px solid #000;
      border-right: 3px solid #000;
      border-bottom: 3px solid #000;
    }
  }
  &--center {
    z-index: 1;
    background: #fc2812;
    border: 3px solid #000;
    &::before {
      content: none;
    }
  }
  &--right {
    margin-top: 5px;
    margin-left: -5px;
    background: #fe523c;
    &::before {
      border-radius: 80px 0 0 80px;
      border-top: 3px solid #000;
      border-bottom: 3px solid #000;
      border-left: 3px solid #000;
    }
  }
}

// 口
.mouse {
  position: relative;
  width: 140px;
  height: 40px;
  margin: -5px auto 0;
  overflow: hidden;
  &::before {
    content: '';
    position: absolute;
    top: -30px;
    left: 0;
    display: block;
    width: 100%;
    height: 70px;
    border-radius: 0 0 70px 70px;
    border-right: 3px solid #000;
    border-bottom: 3px solid #000;
    border-left: 3px solid #000;
  }
}
```

# 制作過程

## 顔

### html

```html
<div class="face"></div>
```

### scss

丸を作成

```scss
.face {
  width: 300px;
  height: 300px;
  border: 3px solid #000;
  border-radius: 50%;
  background: #fe935d;
}
```
### 結果

![face1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/728ce207-4116-c2b4-54bf-7ada77a32342.png)


## 眉毛

### html

```html
<!-- faceの中に入れる -->
<div class="eyebrowsWrapper">
  <dic class="eyebrows eyebrows--left"></div>
  <dic class="eyebrows eyebrows--right"></div>
</div>
```

### scss

```scss
.eyebrowsWrapper {
  display: flex;
  justify-content: space-between;
  width: 190px;
  height: 50px;
  margin: 50px auto 0;
}

.eyebrows {
  width: 70px;
  height: 50px;
  border-radius: 50px 50px 0 0;
  border-top: 3px solid #000;
  border-right: 3px solid #000;
  border-left: 3px solid #000;
}
```

### 結果

![face2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/47e67f11-1834-19b3-5293-75bd8e6ce525.png)


### 説明

#### 1. 眉毛の大枠作成

`.eyebrowsWrapper`で眉毛の配置する場所を作成。(画像の黄色い場所)

![face3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/a9ebc9da-dc6f-3d11-0026-67bc6086496f.png)

#### 2. 眉毛の枠を作成

`.eyebrows`で眉毛を作成。

```scss
.eyebrows {
  width: 70px;
  height: 50px;
  background: #00f;
}
```

![face4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/d2752753-2c96-1922-4f9f-8da52456c65b.png)

#### 3. 上の部分のみ、角をとる

```scss
.eyebrows {
  width: 70px;
  height: 50px;
  background: #00f;
  border-radius: 50px 50px 0 0; // これを追記
}
```

![face5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/56f6ecd1-3282-2bd5-36f0-66577ef404c3.png)

border-radiusについて、

```
border-radius: 左上 右上 右下 左下;
```

のように記載することで、個別に記載を行うことができるため、今回は「左上」と「右上」に50pxの記載を行うことで、上記のような角丸を作成することができる。

詳しくは https://developer.mozilla.org/ja/docs/Web/CSS/border-radius を参照してください。

#### 4. backgroundからborderに変更

今回は、「top, right, left」の3箇所に線を引くため、

```scss
.eyebrows {
  border-top: 3px solid #000;
  border-right: 3px solid #000;
  border-left: 3px solid #000;
}
```

を追加。

![face6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/f749e451-4e79-5eda-2cf0-a27950288a27.png)

## 目

### html

```html
<!-- 目 -->
<div class="eyeWrapper">
  <div class="eye eye--left"></div>
  <div class="eye eye--right"></div>
</div>
```

### scss

```scss
.eyeWrapper {
  display: flex;
  justify-content: space-between;
  width: 160px;
  height: 54px;
  margin: -25px auto 0;
  background: #ff0;
}

.eye {
  width: 40px;
  height: 50px;
  background: #000;
  border-radius: 50%;
}
```

### 結果

![face9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/17cd8a3a-92eb-c1e3-2a83-716795c4774c.png)

### 説明

#### 1. 大枠の作成

`.eyeWrapper`で目の配置する場所を作成。(画像の黄色い場所)

![face7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/339c8eb8-35e6-0ed3-7836-c4731559be68.png)

`.eye`で目を作成。

#### 2. 枠を作成

```scss
.eye {
  width: 40px;
  height: 50px;
  background: #000;
}
```

![face8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/b18e32e4-5af8-4d67-c653-350d61cf9c4f.png)

#### 3. 楕円を作成

```scss
.eye {
  width: 40px;
  height: 50px;
  background: #000;
  border-radius: 50%; // これを追記
}
```

![face9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/17cd8a3a-92eb-c1e3-2a83-716795c4774c.png)

楕円についても、正円の時と同じように、`border-radius: 50%;`で適応されます。


## 鼻

### html

```html
<!-- 鼻・頬 -->
<div class="noseWrapper">
  <div class="nose nose--left"></div>
  <div class="nose nose--center"></div>
  <div class="nose nose--right"></div>
</div>
```

### scss

```scss
.nose {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  &::before {
    content: '';
    display: block;
    width: 60%;
    height: 100%;
  }
  &::after {
    content: '';
    position: absolute;
    top: calc(50% - 6px);
    left: calc(50% - 6px);
    display: block;
    width: 12px;
    height: 12px;
    background: #fff;
  }
  &--left {
    margin-top: 5px;
    margin-right: -5px;
    background: #fe523c;
    &::before {
      margin-left: auto;
      border-radius: 0 70px 70px 0;
      border-top: 3px solid #000;
      border-right: 3px solid #000;
      border-bottom: 3px solid #000;
    }
  }
  &--center {
    z-index: 1;
    background: #fc2812;
    border: 3px solid #000;
    &::before {
      content: none;
    }
  }
  &--right {
    margin-top: 5px;
    margin-left: -5px;
    background: #fe523c;
    &::before {
      border-radius: 70px 0 0 70px;
      border-top: 3px solid #000;
      border-bottom: 3px solid #000;
      border-left: 3px solid #000;
    }
  }
}
```

### 結果

![face15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/c222b82f-0335-ad87-96ce-d103ce65d0ed.png)

### 説明

#### 1. 大枠の作成

`.noseWrapper`で鼻・頬の配置する場所を作成。(画像の黄色い場所)

![face10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/7586988e-3713-4480-26d7-79ba7f21f66b.png)

#### 2. 鼻の枠を作成

`.nose`で鼻・頬を作成

```scss
// 鼻・頬に共通するスタイル(鼻・頬のサイズを作成)
.nose {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 50%;
}

// 左頬のスタイル
.nose--left {
  background: #fe523c;
}

// 鼻のスタイル
.nose--center {
  background: #fc2812;
}

// 右頬のスタイル
.nose--right {
  background: #fe523c;
}
```

![face11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/85d6844c-990f-af40-9cc3-f231c25bc029.png)

#### 3-1. 頬の位置を調整

このままだと違和感があるので、鼻と頬が微妙に重なるように変更する

```scss
// 左頬のスタイル
.nose--left {
  margin-top: 5px;
  margin-right: -5px;
}

// 右頬のスタイル
.nose--right {
  margin-top: 5px;
  margin-left: -5px;
}
```

![face12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/f753f925-d7db-3801-101f-a3a998aead44.png)

#### 3-2. 頬の位置を調整(鼻の重なりを調整)

現時点だと「左頬 → 鼻 → 右頬」の順番で要素が重なっているため、鼻の`z-index`の値を追加することで、「左頬 → 右頬 → 鼻」の順番に重なりを変更します。

```scss
// 鼻・頬に共通するスタイル(鼻・頬のサイズを作成)
.nose {
  position: relative;
}

// 鼻のスタイル
.nose--center {
  z-index: 1;
}
```

![face13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/b4347872-9abe-f819-a709-d7fdea0948a4.png)

#### 4. 中央に白い四角を配置

cssで要素を中央に寄せる方法として、今回は固定の値のため、`calc(50% - 要素のサイズ / 2)`を使用して、合わせます。

```scss
// 鼻・頬の中央にある四角
.nose::after {
  content: '';
  position: absolute;
  top: calc(50% - 6px);
  left: calc(50% - 6px);
  display: block;
  width: 12px;
  height: 12px;
  background: #fff;
}
```

![face14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/0cdacd88-940f-07c4-dfb3-686751c443c6.png)

#### 5-1. 鼻に輪郭を配置

鼻については、全体に配置をするため、通常の`border`を使用。

```scss
// 鼻のスタイル
.nose--center {
  border: 3px solid #000;
}
```

#### 5-2. 頬に輪郭を配置

```scss
// 鼻・頬に共通するスタイル(鼻・頬のサイズを作成)
.nose::before {
  content: '';
  display: block;
  width: 60%;
  height: 100%;
}

// 左頬のスタイル
.nose--left::before {
  margin-left: auto;
  border-radius: 0 80px 80px 0;
  border-top: 3px solid #000;
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
}

// 鼻のスタイル
.nose--center::before {
  content: none; // display: none;でもよいが、擬似要素だとcontent: none;で要素を表示させないこともできる。
}

// 右頬のスタイル
.nose--right::before {
  border-radius: 80px 0 0 80px;
  border-top: 3px solid #000;
  border-bottom: 3px solid #000;
  border-left: 3px solid #000;
}
```

![face15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/c222b82f-0335-ad87-96ce-d103ce65d0ed.png)

#### 補足

「4-2. 頬に輪郭を配置」の部分について、別の方法として、要素自体に`border`を引く方法もあるが、その場合、以下のような状態(左頬の部分)になってしまうため、今回は`before`要素を使用し、半円で対応。

![face16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/40c2d68b-0a52-efe2-d1ac-9df7eee9e295.png)

## 口

### html

```html
<div class="mouse"></div>
```

### scss

```scss
// 口
.mouse {
  position: relative;
  width: 140px;
  height: 40px;
  margin: -5px auto 0;
  overflow: hidden;
  &::before {
    content: '';
    position: absolute;
    top: -30px;
    left: 0;
    display: block;
    width: 100%;
    height: 70px;
    border-radius: 0 0 70px 70px;
    border-right: 3px solid #000;
    border-bottom: 3px solid #000;
    border-left: 3px solid #000;
  }
}
```

### 結果

![face17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/ca0ed404-126b-9a24-54eb-17185d19e874.png)

### 説明

#### 1. 口の表示させる部分の配置

```scss
.mouse {
  position: relative;
  width: 140px;
  height: 40px;
  margin: -5px auto 0;
  background: #00f;
}
```

![face18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/7f733cce-b3af-01a8-17c8-8821699b9dde.png)

#### 2. 曲線が適応されるように記載

`.mouse`を

```scss
.mouse {
  position: relative;
  width: 140px;
  height: 40px;
  margin: 0 auto;
  border-radius: 0 0 40px 40px; // ここにborder-radiusを追加
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
  border-left: 3px solid #000;
}
```

のように対応を行った場合、以下の画像のような状態になってしまうため、`before`要を作成して対応を行う。

![face19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/71c96548-1df1-59c3-3d77-7cfd84c7e39f.png)

#### 3. `before`要素で曲線の部分を作成する

```scss
.mouse::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 70px;
  border-radius: 0 0 70px 70px;
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
  border-left: 3px solid #000;
}
```

![face20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/707ff686-41d4-9d6d-eb9c-45bb507ae188.png)

#### 4. 位置の調整

高さを70pxで設定したため、

「既存の高さ(40px) - 設定した高さ(70px) = -30px」なので、topの値を-30pxに変更。

```scss
.mouse::before {
  content: '';
  position: absolute;
  top: -30px; // ここの値を変更
  left: 0;
  display: block;
  width: 100%;
  height: 70px;
  border-radius: 0 0 70px 70px;
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
  border-left: 3px solid #000;
}
```

![face21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/15ff7094-3f17-40f7-d6cc-2f85eb414965.png)

#### 5-1. はみ出している場所の非表示

はみ出している部分については、親要素に`overflow: hidden`を追加。

```scss
.mouse {
  position: relative;
  width: 140px;
  height: 40px;
  margin: 0 auto;
  overflow: hidden; // これを追加
}
```

![face22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/0595b567-ef58-dccf-4059-0afa3be44a89.png)

#### 5-2. 余白調整

最後に頬と口の間に隙間があるため、最後に余白の調整を行う

```scss
.mouse {
  position: relative;
  width: 140px;
  height: 40px;
  margin: -5px auto 0; // margin-top: -5px;に変更
  overflow: hidden;
}
```

![face23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214546/c989c5f6-fcf5-2ad4-bd5f-94de54631e24.png)

# 最後に

初めてcssでキャラクターを記載して見ましたが、意外と楽しかったので、また機会があればQiitaにまとめますので、よろしくお願いします！

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