Shopifyのグローバルメニューに個別のアイコンを付ける方法

前回予告しました通り、今回の記事はShopifyのグローバルメニューに個別のアイコンを付ける方法をご紹介します。

WordPressであればメニューそれぞれにクラスを付けられるので、Font AwesomeなどのアイコンフォントをCSSで出力したりが可能ですが、Shopifyの場合はそれが出来ないため、メニュー周りのデザインにお悩みの方も多いかと思われます。

中にはメニュー機能を使わずに、HTMLで直接メニューを書いちゃうような不細工なやり方をしてるケースも多いんじゃないでしょうか?

しかし、出来ちゃうんですよね〜これが。

まずはクラスを付ける方法からご紹介していきましょう。

1. メニューにクラスを付ける方法

これは前回の応用ですね。

英語と日本語を並列表記させるために使った技とほぼ同じで、まずはメニュー名をスラッシュ区切りで登録します。

Home/ホーム

これを分解して出力するのには、以下のコードにします。

{{ link.title | split: '/' | first }} → Home
{{ link.title | split: '/' | last }} → ホーム

クラスが全て小文字の場合は、英字を全て小文字にするdowncaseを付けるだけ。

{{ link.title | split: '/' | first | downcase }} → home

また、全て大文字で出力したい場合はupcaseを付けて下さい。

{{ link.title | split: '/' | first | upcase }} → HOME

これをassignで簡略化し{{ menu_class }}で出力できるようにします。

{% assign menu_class = link.title | escape | split: '/' | first | downcase %}

Font Awesomeなどアイコンフォントで出力される場合は、HTMLタグにクラスを追記しCSSでそれぞれ指定するだけですね。
テーマがDawnの場合は「sections/header.liquid」内にあるグローバルメニューを出力するソースを、ハイライト部分を参考に編集してください。

{%- if section.settings.menu != blank -%}
  <nav class="header__inline-menu">
    <ul class="list-menu list-menu--inline" role="list">
      {%- for link in section.settings.menu.links -%}
        <li>
          {%- if link.links != blank -%}
          {% assign menu_class = link.title | escape | split: '/' | first | downcase %}
            <details-disclosure>
              <details>
                <summary class="header__menu-item list-menu__item link focus-inset {{ menu_class }}">
                  <span {% if link.child_active %} class="header__active-menu-item"{% endif %}>{{ link.title | escape | split: '/' | last }}</span>
                  {% render 'icon-caret' %}
                </summary>
                <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1">
                  {%- for childlink in link.links -%}
                    <li>
                      {%- if childlink.links == blank -%}
                        <a href="{{ childlink.url }}" class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if childlink.current %} list-menu__item--active{% endif %}"{% if childlink.current %} aria-current="page"{% endif %}>
                          {{ childlink.title | escape }}
                        </a>
                      {%- else -%}
                        <details>
                          <summary class="header__menu-item link link--text list-menu__item focus-inset caption-large">
                            {{ childlink.title | escape }}
                            {% render 'icon-caret' %}
                          </summary>
                          <ul class="header__submenu list-menu motion-reduce">
                            {%- for grandchildlink in childlink.links -%}
                              <li>
                                <a href="{{ grandchildlink.url }}" class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if grandchildlink.current %} list-menu__item--active{% endif %}"{% if grandchildlink.current %} aria-current="page"{% endif %}>
                                  {{ grandchildlink.title | escape }}
                                </a>
                              </li>
                            {%- endfor -%}
                          </ul>
                        </details>
                      {%- endif -%}
                    </li>
                  {%- endfor -%}
                </ul>
              </details>
            </details-disclosure>
          {%- else -%}
            <a href="{{ link.url }}" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset {{ menu_class }}"{% if link.current %} aria-current="page"{% endif %}>
              <span {% if link.current %} class="header__active-menu-item"{% endif %}>{{ link.title | escape | split: '/' | last }}</span>
            </a>
          {%- endif -%}
        </li>
      {%- endfor -%}
    </ul>
  </nav>
{%- endif -%}

メニュー名を出力する<span>タグの親タグに{{ menu_class }}を追記しクラスが出力されるようにしました。

ちなみにリンク先のハンドルからクラス名を生成するやり方もありますが、Homeやドロップダウン用の空リンクなどハンドルが無い場合は分岐が必要になって面倒なので、この方法が最適だと思います。

後はそれぞれのアイコンが疑似属性で表示されるように、CSSをに追記してください。

.list-menu__item::before {
	font-family: "Font Awesome 5 Free";
}
.list-menu__item.home::before {
	content: "\f015";
	display: inline-block;
}

デザインはお好みで!

2. SVGアイコンを出力させる方法

アイコンフォントは簡単でいいのですが、Googleのサイトスピード評価に悪影響なので使わないのがトレンド。

実際に使うことのないアイコンを大量に読み込んでいるわけですし、特にECサイトなら表示スピードを少しでも速くしたいところ。

そんな時に便利なのがSVGアイコンですね。

Shopifyのテーマのほとんどが、SVGアイコンを採用しているんじゃないでしょうか?

ただほとんどテーマが、Snippetsに大量のアイコンを登録していてカオス状態なので、今回は複数のSVGアイコンを1ファイルにまとめちゃいましょう!

まずは「新しいsnippetを追加する」より「nav-icons.liquid」を作成し、以下の様にcase/whenを使ってメニューに使う全SVGデータを貼り付けます。

{%- case nav-icons -%}
	{%- when 'home' -%}
		<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path d="M15,2.3l-.719.687-13,13,1.438,1.438L4,16.141V27.7h9v-10h4v10h9V16.141l1.281,1.281,1.438-1.438-13-13Zm0,2.844,9,9V25.7H19v-10H11v10H6V14.141Z"/></svg>
	{%- when 'collections' -%}
		<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path d="M15,2a10.258,10.258,0,0,0-2.812.531c-.852.258-1.477.524-1.5.531h-.032l-2.875.969-.093.031c-.059.016-.153.043-.376.126L7,4.281v.031a5.61,5.61,0,0,0-2.906,2.75A13.947,13.947,0,0,0,3,11.969V14H7V28H23V14h4V11.906s-.086-.847-.25-1.875a8.01,8.01,0,0,0-.906-3.062A7.176,7.176,0,0,0,23,4.375V4.281l-.406-.125c-.059-.027-.047-.011-.094-.031l-.188-.063-2.968-1h-.032c-.023-.007-.648-.273-1.5-.531A10.258,10.258,0,0,0,15,2Zm0,2a10.586,10.586,0,0,1,2.219.469c.207.062.2.066.375.125-.063.094-.11.183-.188.281A2.816,2.816,0,0,1,15,6a2.816,2.816,0,0,1-2.406-1.125c-.078-.1-.125-.187-.188-.281.18-.059.168-.063.375-.125A10.586,10.586,0,0,1,15,4ZM10.438,5.219a5.445,5.445,0,0,0,.593.906,5.138,5.138,0,0,0,7.938,0,5.445,5.445,0,0,0,.593-.906l1.438.5V26H9V5.719ZM7,6.562V12H5a13.4,13.4,0,0,1,.906-4.062A3.638,3.638,0,0,1,7,6.562Zm16,.157a5.589,5.589,0,0,1,1.156,1.312,9.881,9.881,0,0,1,.625,2.313c.145.886.211,1.578.219,1.656H23Z"/></svg>
	{%- when 'brands' -%}
		<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path d="M13.8,2.3l-.313.281-11,11L1.8,14.3l.687.719,9,9,.719.687.719-.687,11-11L24.2,12.7V2.3Zm.844,2H22.2v7.562l-10,10L4.641,14.3ZM25.2,5.3v2h1v8.156l-9.5,9.438-1.25-1.25-1.406,1.406,1.937,1.969.719.687.688-.687L27.922,16.609,28.2,16.3V5.3Zm-6,1a1,1,0,1,0,1,1A1,1,0,0,0,19.2,6.3Z"/></svg>
	{%- when 'contact' -%}
		<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"><path d="M2,6V24H28V6ZM6.312,8H23.688L15,13.781ZM4,8.875l10.438,6.969.562.344.562-.344L26,8.875V22H4Z"/></svg>
{%- endcase -%}

この時に{%- when '○○○' -%}○○○部分は、1で出力するクラスと同等に登録し、<svg>タグに対してクラスやその他の属性を設けたい場合は、自由に追記して下さい。

SVGアイコンの作り方については、省略させていただきます。
作る環境のない方は、検索してフリーのSVGアイコンなどをご利用下さい。

続けて1と同様に「sections/header.liquid」のグローバルメニュー部分を編集します。

{%- if section.settings.menu != blank -%}
  <nav class="header__inline-menu">
    <ul class="list-menu list-menu--inline" role="list">
      {%- for link in section.settings.menu.links -%}
        <li>
          {%- if link.links != blank -%}
          {% assign menu_class = link.title | escape | split: '/' | first | downcase %}
            <details-disclosure>
              <details>
                <summary class="header__menu-item list-menu__item link focus-inset {{ menu_class }}">
                  {% render 'nav-icons' with menu_class %}
                  <span {% if link.child_active %} class="header__active-menu-item"{% endif %}>{{ link.title | escape | split: '/' | last }}</span>
                  {% render 'icon-caret' %}
                </summary>
                <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1">
                  {%- for childlink in link.links -%}
                    <li>
                      {%- if childlink.links == blank -%}
                        <a href="{{ childlink.url }}" class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if childlink.current %} list-menu__item--active{% endif %}"{% if childlink.current %} aria-current="page"{% endif %}>
                          {{ childlink.title | escape }}
                        </a>
                      {%- else -%}
                        <details>
                          <summary class="header__menu-item link link--text list-menu__item focus-inset caption-large">
                            {{ childlink.title | escape }}
                            {% render 'icon-caret' %}
                          </summary>
                          <ul class="header__submenu list-menu motion-reduce">
                            {%- for grandchildlink in childlink.links -%}
                              <li>
                                <a href="{{ grandchildlink.url }}" class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if grandchildlink.current %} list-menu__item--active{% endif %}"{% if grandchildlink.current %} aria-current="page"{% endif %}>
                                  {{ grandchildlink.title | escape }}
                                </a>
                              </li>
                            {%- endfor -%}
                          </ul>
                        </details>
                      {%- endif -%}
                    </li>
                  {%- endfor -%}
                </ul>
              </details>
            </details-disclosure>
          {%- else -%}
            <a href="{{ link.url }}" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset {{ menu_class }}"{% if link.current %} aria-current="page"{% endif %}>
              {% render 'nav-icons' with menu_class %}
              <span {% if link.current %} class="header__active-menu-item"{% endif %}>{{ link.title | escape | split: '/' | last }}</span>
            </a>
          {%- endif -%}
        </li>
      {%- endfor -%}
    </ul>
  </nav>
{%- endif -%}

上記のハイライト部分の{% render 'nav-icons' with menu_class %}を追記しました。

この1行で先程登録したSVGアイコンが個別で出力されます。
Shopify用のSVGスプライトですね。

アイキャッチ画像の様にアイコンに加え全て大文字の英語表記と小さめの日本語を並列で出力させたい場合は、以下を参考に設定して下さい。

{%- if section.settings.menu != blank -%}
  <nav class="header__inline-menu">
    <ul class="list-menu list-menu--inline" role="list">
      {%- for link in section.settings.menu.links -%}
        <li>
          {%- if link.links != blank -%}
          {% assign menu_class = link.title | escape | split: '/' | first | downcase %}
            <details-disclosure>
              <details>
                <summary class="header__menu-item list-menu__item link focus-inset {{ menu_class }}">
                  {% render 'nav-icons' with menu_class %}
                  <span {% if link.child_active %} class="header__active-menu-item"{% endif %}>
                  	<strong>{{ link.title | escape | split: '/' | first | upcase }}</strong>
                  	<small>{{ link.title | escape | split: '/' | last }}</small>
                  </span>
                  {% render 'icon-caret' %}
                </summary>
                <ul class="header__submenu list-menu list-menu--disclosure caption-large motion-reduce" role="list" tabindex="-1">
                  {%- for childlink in link.links -%}
                    <li>
                      {%- if childlink.links == blank -%}
                        <a href="{{ childlink.url }}" class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if childlink.current %} list-menu__item--active{% endif %}"{% if childlink.current %} aria-current="page"{% endif %}>
                          {{ childlink.title | escape }}
                        </a>
                      {%- else -%}
                        <details>
                          <summary class="header__menu-item link link--text list-menu__item focus-inset caption-large">
                            {{ childlink.title | escape }}
                            {% render 'icon-caret' %}
                          </summary>
                          <ul class="header__submenu list-menu motion-reduce">
                            {%- for grandchildlink in childlink.links -%}
                              <li>
                                <a href="{{ grandchildlink.url }}" class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if grandchildlink.current %} list-menu__item--active{% endif %}"{% if grandchildlink.current %} aria-current="page"{% endif %}>
                                  {{ grandchildlink.title | escape }}
                                </a>
                              </li>
                            {%- endfor -%}
                          </ul>
                        </details>
                      {%- endif -%}
                    </li>
                  {%- endfor -%}
                </ul>
              </details>
            </details-disclosure>
          {%- else -%}
            <a href="{{ link.url }}" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset {{ menu_class }}"{% if link.current %} aria-current="page"{% endif %}>
              {% render 'nav-icons' with menu_class %}
              <span {% if link.current %} class="header__active-menu-item"{% endif %}>
              	<strong>{{ link.title | escape | split: '/' | first | upcase }}</strong>
              	<small>{{ link.title | escape | split: '/' | last }}</small>
              </span>
            </a>
          {%- endif -%}
        </li>
      {%- endfor -%}
    </ul>
  </nav>
{%- endif -%}

SVGアイコンで出力する場合クラスは必要ないかもしれませんが、個別にリンク色を変えたりすることも出来ますし、特に邪魔にはならないのでやっておいて損はないでしょう。

後はお好みでデザインしていただければと思います。

以上、Shopifyのグローバルメニューに個別のアイコンを付ける方法でした〜

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です