文字の回り込みを図形で制御できるCSS Shapesを勉強してみた

文字の回り込みを制御できるCSS Shapesについて参考サイトを元に自分なりに勉強したことを書いていきます
**間違ってたら指摘お願いします**

# 参考

- [矩形レイアウトを超えた !? – CSS Shapes で Web のレイアウトはもっと自由になる – PSYENCE:MEDIA](https://tech.recruit-mp.co.jp/front-end/try-css-shapes/)
- [Art Direction For The Web Using CSS Shapes — Smashing Magazine](https://www.smashingmagazine.com/2019/04/art-direction-for-the-web-using-css-shapes/)

**私の記事はブラウザバックしてもらえればいいのですが、↑のページは読む価値あると思います！**

# ブラウザ対応

https://caniuse.com/#feat=css-shapes

<img width="1277" alt="Screen Shot 2019-05-18 at 16.40.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/9dc25745-478c-8e1a-c10b-a3e06c1959f5.png">

IE、Edge以外は動くようです (2019/05/18現在)

# CSS Shapesとは

CSSで図形を設定して、その形にテキストを流し込むことができます。 `shape-outside`、` shape-margin`、`shape-image-threshold`のプロパティで定義します

# 基本的な例

```html:html
<img src="ball.png" alt="バスケットボール">
<p>
    おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。
    おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。
    おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。おはようございます。
</p>
```

```css:css
img {
    float: left;
    shape-outside: circle(50%);
}
```

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

cssで`circle(50%)`と設定したので、それに合わせて文字が円形に回り込んでくれました

# shape-outside

https://developer.mozilla.org/en-US/docs/Web/CSS/shape-outside

隣接する文字の回り込み方法を指定できます

※参考リンク引用

```
/* Keyword values */
shape-outside: none;
shape-outside: margin-box;
shape-outside: content-box;
shape-outside: border-box;
shape-outside: padding-box;

/* Function values */
shape-outside: circle();
shape-outside: ellipse();
shape-outside: inset(10px 10px 10px 10px);
shape-outside: polygon(10px 10px, 20px 20px, 30px 30px);

/* <url> value */
shape-outside: url(image.png);

/* <gradient> value */
shape-outside: linear-gradient(45deg, rgba(255, 255, 255, 0) 150px, red 150px);

/* Global values */
shape-outside: initial;
shape-outside: inherit;
shape-outside: unset;
```

## shape-box

- margin-box
- border-box
- padding-box
- content-box

### `margin-box`

文字を`margin`に合わせて回り込むようにする

```css
.hoge {
    float: left;
    shape-outside: margin-box;
}
```

### `border-box`

文字を`border`に合わせて回り込むようにする

```css
.hoge {
    float: left;
    shape-outside: border-box;
}
```

### `padding-box`

文字を`padding`に合わせて回り込むようにする

```css
.hoge {
    float: left;
    shape-outside: padding-box;
}
```

### `content-box`

文字を`padding`より内側の部分に合わせて回り込むようにする

```css
.hoge {
    float: left;
    shape-outside: content-box;
}
```


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

## basic-shape

https://developer.mozilla.org/en-US/docs/Web/CSS/basic-shape

### `inset()`

四角形が内側にあるように文字の回り込みを指定できます

```html:html
<div></div>
<p>
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
    Good morning! Good morning! Good morning! Good morning! Good morning! Good morning! 
</p>
```

```css:css
div {
    background: seagreen;
    float: left;
    height: 200px;
    width: 200px;
    float: left;
    shape-outside: inset(50px 30px 70px 30px);
}
```

上、右、下、左で指定していますので、以下のような感じで文字が回り込んでくれます

<img width="636" alt="Screen Shot 2019-05-18 at 22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/6aa6ab51-8456-9e70-e553-deb41a1e8b5f.png">


```css:css
div {
    float: left;
    shape-outside: inset(50px); /* 上右下左を50pxで指定 */
}
```

```css:css
div {
    float: left;
    shape-outside: inset(50px round 30px); /* 上右下左を50px、角丸を30pxで指定 */
}
```

```css:css
div {
    float: left;
    shape-outside: inset(50px 25px) /* 上下、右左で指定 */
}
```

```css:css
div {
    float: left;
    shape-outside: inset(15% 25px 30% round 20% 70%) /* 上、右左、下、角丸を左上右下70%、右上左下20%で指定 */
}
```

<img width="326" alt="Screen Shot 2019-05-18 at 23.14.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/f3425159-08a2-badf-28b5-afbca11dd0a1.png">

↓もう少し動きがわかりやすいサンプルです

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

---

`inset()` だけではないですが、先ほどの`margin-box`、`border-box`、`padding-box`、`content-box`と一緒に使えます

```css:css
div {
    background: seagreen;
    border: 30px solid orange;
    float: left;
    height: 100px;
    width: 100px;
    float: left;
}

div.box1 {
    shape-outside: inset(10%) border-box;
}

div.box2 {
    shape-outside: inset(10%) content-box;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/73b59bf6-387a-a83d-5acb-928091a4491f.png)

### `circle()`

円の形で指定できます

```css:css
div {
    background: seagreen;
    height: 200px;
    width: 200px;
    float: left;
    shape-outside: circle(50%);
}
```

円の半径を50% = boxいっぱいを指定

<img width="641" alt="Screen Shot 2019-05-19 at 0.09.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/cc9239cb-b9d5-2e62-ae3d-5e561974ed51.png">

<img width="309" alt="Screen Shot 2019-05-19 at 0.10.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/df53e86e-4f0d-5ff2-fb2f-91811907d477.png">

```css:css
div {
    background: seagreen;
    height: 200px;
    width: 200px;
    float: left;
    shape-outside: circle(50% at 35% 65%);
}
```

`at`でpositionのx、yを指定

<img width="641" alt="Screen Shot 2019-05-19 at 0.12.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/d51a24a9-fa6a-6c99-6abb-37dd62085f11.png">

<img width="316" alt="Screen Shot 2019-05-19 at 0.13.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/78e3b03a-31f5-8d74-4b56-5d6de8aa17d0.png">

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

### `ellipse()`

楕円形で指定できます

```css:css
div {
    background: seagreen;
    height: 200px;
    width: 200px;
    float: left;
    shape-outside: ellipse(50% 25% at 50% 50%);
}
```

`ellipse(半径横 半径縦 at 横位置 縦位置);` で楕円形を指定します

<img width="641" alt="Screen Shot 2019-05-19 at 1.36.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/91527f4e-f0a5-a134-53e6-1f0344ee0b58.png">

<img width="375" alt="Screen Shot 2019-05-19 at 1.38.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/aac53553-3cd5-a800-83d6-d97b1a9ab756.png">

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

### `polygon()`

座標指定で複雑な図形を指定することができます

```css:css
div {
    float: left;
    shape-outside: polygon(50% 0%, 66% 33%, 100% 34%, 75% 63%, 84% 100%, 51% 77%, 15% 99%, 27% 62%, 0 35%, 36% 33%);
}
```

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

- こちらのサイトを使うと簡単にpathが作成できました

https://bennettfeely.com/clippy/

![fRxvLF9txn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/9dfa3a2c-3fbd-0be4-7c25-c1762d1e7324.gif)

# shape-margin

余白を設定

```css:css
div {
    background: seagreen;
    height: 200px;
    width: 200px;
    float: left;
    clip-path: polygon(0 0, 150px 150px, 0 150px);
    shape-outside: polygon(0 0, 150px 150px, 0 150px);
    shape-margin: 20px;
}
```

<img width="612" alt="Screen Shot 2019-05-19 at 13.35.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/0103726e-3b6f-3aa2-f61b-bc43bb2d0ed3.png">





# shape-image-threshold

https://developer.mozilla.org/en-US/docs/Web/CSS/shape-image-threshold

画像の透明度を指定して、そこに合わせて文字を回り込ませてくれます

例えばこちらの画像を使うと、

![Screen Shot 2019-05-19 at 3.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/3bf8f534-eb8c-3c1d-bce7-802091a517b8.png)

```css:css
img {
    float: left;
    shape-outside: url('./amagaeru.png');
    shape-image-threshold: 0;
}
```

このように、透過部分に合わせてくれます

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

---

`linear-gradient`で調整することもできるようです

```css:css
div {
    background: linear-gradient(50deg, rgb(77, 26, 103), transparent 60%, transparent);
    height: 200px;
    width: 200px;
    float: left;
    shape-outside: linear-gradient(50deg, rgb(77, 26, 103), transparent 60%, transparent);
    shape-image-threshold: .2;
}
```

<img width="659" alt="Screen Shot 2019-05-19 at 4.13.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/b08a53a0-cd6c-ef89-eb31-2e9c03dbe3df.png">


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

---

最後まで読んでくれてありがとうございましたm(_ _)m