レスポンシブロゴをsvgファイル1つで実現する

## この記事の概要

`レスポンシブロゴ`をご存じでしょうか。

デスクトップからスマートフォンまで、どんなサイズのディスプレイにロゴが表示されるかは予想がつきません。
同じ見た目のロゴを拡大縮小しても、あまり見目良くならない場合もあるでしょう。

そのため`レスポンシブロゴ`と呼ばれる手法でロゴのバリエーションを定義する企業・サービスもあります。

ただ、これを実現するために毎回`srcset`に複数のパスを指定するのも面倒です。[^1]
クライアントにたくさんの種類のロゴを渡して「〇px以下のときはこちらを使ってください」などとお願いするのも申し訳がありません。

[^1]: コンポーネント化してしまえば良いんですけどね。

というわけで、1つのsvgファイルだけでレスポンシブロゴを実現する方法を記事にしました。

## 作り方

### 各パターンのロゴの用意

まずは、すべてのサイズごとのロゴを作ります。

今回は分かりやすいように`Large` `Medium` `Small`の3種類のテキストを並べています。
実際に作る際は、`シンボル + ロゴタイプ` `ロゴタイプのみ` `シンボルのみ`のような構成になるでしょう。

1つの矩形の中に配置して、それぞれのパターンが分かりやすいように色分けしておきます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8908a3c6-0ef1-c2dc-d933-95febd9d9857.png)

これをsvgとして書き出します。
現段階ではこんなイメージです。

```xml
<svg width="400" height="198" viewBox="0 0 400 198" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="..." fill="#FF0000"/> <!-- Smallのパス -->
  <path d="..." fill="#0000FF"/> <!-- Mediumのパス -->
  <path d="..." fill="#00FF00"/> <!-- Largeのパス -->
</svg>
```

### グループに分割

次に、今のsvgを`class`つきのグループに分割します。

```diff_xml
  <svg width="400" height="198" viewBox="0 0 400 198" fill="none" xmlns="http://www.w3.org/2000/svg">
+   <g class="small">
      <path d="..." fill="#FF0000"/>
+   </g>
+   <g class="medium">
      <path d="..." fill="#0000FF"/>
+   </g>
+   <g class="large">
      <path d="..." fill="#00FF00"/>
+   </g>
  </svg>
```

### メディアクエリの指定

次に、svgの中でメディアクエリを指定します。
今回は以下の設定でいきます。

- 200px以下
  - Small
- 200pxから400px以下
  - Medium
- 400pxから
  - Large

```diff_xml
  <svg width="400" height="198" viewBox="0 0 400 198" fill="none" xmlns="http://www.w3.org/2000/svg">
+   <style type="text/css">
+     .large {
+       display: block;
+     }
+     .medium {
+       display: none;
+     }
+     .small {
+       display: none;
+     }
+     @media (max-width: 400px) {
+       .large {
+         display: none;
+       }
+       .medium {
+         display: block;
+       }
+     }
+     @media (max-width: 200px) {
+       .medium {
+         display: none;
+       }
+       .small {
+         display: block;
+       }
+     }
+   </style>
    <g class="small">
      <path d="..." fill="#FF0000"/>
    </g>
    <g class="medium">
      <path d="..." fill="#0000FF"/>
    </g>
    <g class="large">
      <path d="..." fill="#00FF00"/>
    </g>
  </svg>
```

### 色の修正

見分けやすくするために色を原色で塗り分けていましたが、もう必要無いので本来の色に戻します。

```diff_xml
  <svg width="400" height="198" viewBox="0 0 400 198" fill="none" xmlns="http://www.w3.org/2000/svg">
    <style type="text/css">
      .large {
        display: block;
      }
      .medium {
        display: none;
      }
      .small {
        display: none;
      }
      @media (max-width: 400px) {
        .large {
          display: none;
        }
        .medium {
          display: block;
        }
      }
      @media (max-width: 200px) {
        .medium {
          display: none;
        }
        .small {
          display: block;
        }
      }
    </style>
    <g class="small">
-     <path d="..." fill="#FF0000"/>
+     <path d="..." fill="black"/>
    </g>
    <g class="medium">
-     <path d="..." fill="#0000FF"/>
+     <path d="..." fill="black"/>
    </g>
    <g class="large">
-     <path d="..." fill="#00FF00"/>
+     <path d="..." fill="black"/>
    </g>
  </svg>
```

## 完成

ここまでの内容をすべて反映させると下の動画のようになります。
（HTML側に複数`img`を設置していないよ、と示したくてコードも表示していましたが、全然見えませんね……）

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/a32bb291-4b51-b288-d93b-b32fb7471578.gif)

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox