css では実現できない無茶振りデザインを Vue と SVG で実装する

## デザイナーの無茶振り

こんな吹き出し実装してと言われたことありませんか？

<img width="195" alt="スクリーンショット 2019-11-05 0.33.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5565/d676db98-78d0-2a75-f061-aab24d79eca6.png">

テキストの部分は動的に変わりますよっていうパーツです。

これどうやって css で実現するかとか考える。

- トリッキーな css 書いて調整するのもめんどくさい。△ はギリギリできるけど、枠線つけるのは無理。
- 話してデザイン調整するのもめんどくさい。

## css は捨てて、SVG に
- SVG にして HTML に埋め込めば簡単では？
- Vue.js なら svg を template にうめこめるはず。

[ドキュメント](https://jp.vuejs.org/v2/cookbook/editable-svg-icons.html)を見るとできそう。

## やってみた

adobeXD で作成したバルーンを svg で出力して、vue はりつけました。

```vuejs

<template>
  <!-- eslint-disable max-len -->
  <div v-bind:style="{ display: 'inline-block', width: size }">
    <svg viewBox="0 0 209.001 51">
      <defs>
          <filter id="合体_1" width="209.001" height="51" x="0" y="0" filterUnits="userSpaceOnUse">
              <feOffset dx="3" dy="3"/>
              <feGaussianBlur result="blur" stdDeviation="1.5"/>
              <feFlood flood-color="#5d5d5d" flood-opacity=".161"/>
              <feComposite in2="blur" operator="in"/>
              <feComposite in="SourceGraphic"/>
          </filter>
      </defs>
      <g id="サジェストバルーン" transform="translate(1.5 1.5)">
          <g class="cls-5" transform="translate(-1.5 -1.5)">
              <g id="合体_1-2" class="cls-1" data-name="合体 1">
                  <path d="M-7208.498 45.5H-7371.5a17.882 17.882
                  0 0 1-12.728-5.271c-3.399-3.4-5.272-7.92-5.272-12.728s1.873-9.329 5.272-12.728c3.4-3.4
                    7.92-5.272 12.728-5.272h78.001l.15-.2 3.35-4.467 3.35 4.467.15.2h78.001c4.808 0 9.328
                    1.872 12.727 5.272 3.4 3.4 5.273 7.92 5.273 12.728s-1.873 9.328-5.273 12.728c-3.399
                    3.4-7.92 5.272-12.727 5.272z" class="cls-3" transform="rotate(180 -3594.25 23.75)"
                    />
                  <path d="M-7208.498 45c4.674 0 9.069-1.82 12.374-5.125a17.385 17.385 0 0 0
                  5.126-12.374c0-4.675-1.82-9.07-5.126-12.375a17.385 17.385 0 0 0-12.374-5.125h-78.25l-.3-.4-2.951-3.934-2.95
                  3.934-.3.4h-78.25c-4.675 0-9.07 1.82-12.375 5.125A17.386 17.386 0 0 0-7389 27.501c0 4.674 1.82 9.069 5.126
                    12.374a17.386 17.386 0 0 0 12.374 5.126h163.002m0 1H-7371.5c-10.217 0-18.5-8.283-18.5-18.5 0-10.218 8.283-18.5
                    18.5-18.5h77.751l3.75-5 3.75 5h77.751c10.217 0 18.5 8.282 18.5 18.5 0 10.217-8.283 18.5-18.5 18.5z"
                      class="cls-4"
                      transform="rotate(180 -3594.25 23.75)"
                      />
              </g>
          </g>
          <text id="テキスト" x="50%" y="50%" text-anchor="middle" class="cls-2">
              <slot></slot>
          </text>
      </g>
    </svg>
  </div>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue';

export default Vue.extend({
  props: {
    size: {
      type: String as PropType<string>,
      default: '100%',
    },
  },
});
</script>
<style>

    .cls-1{fill:#fff}
    .cls-2,.cls-4{fill:#2f73dd}
    .cls-2{font-size:12px;}
    .cls-3,.cls-4{stroke:none}
    .cls-5{filter:url(#合体_1)}
</style>
```

#### やったこと
重要な変更は、これだけです。
- svg 内のstyle 要素は、style　に移動
- テキストを入れたいところは、slot に変更

## 課題とか
- css と比較すると、本当にそのまま表現できるし、実装コストもほとんどかからないので圧勝です。
- デザインツール使えない人には辛いかもですが、デザイナーさんに頼めば OK かな？
- 課題は、吹き出しサイズをオーバした場合、勝手に大きくなって欲しい(html の auto的な）です（やり方がよくわからない）