勇者(さかもっちゃん) 弊社若手エンジニアがShopifyでRPG風サイトを制作中!遊んで行ってね!
MORE

BLOG

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう

  • ECサイト
  • Shopify
  • ThemeBlocks
  • サイト構築
  • テーマカスタマイズ
  • 開発
25.08.25

1. はじめに

1.1 記事について

この記事ではShopify Winter Editions ‘25のアップデート機能の一つTheme Blocksについて、Webデザインを意識した万能セクションの開発にチャレンジしてみたいと思います。

1.2 記事の対象

この記事は、Shopifyテーマ開発者に向けて記載しております。

1.3 記事

この記事を読み終えるまでに、約10分です。

2. Shopify Theme Blocksでできること

2.1 Shopify Theme Blocksの基本仕様

Theme Blocksは簡単に言うと、セクション内で自由にブロック配置ができる機能です。 今まではセクション毎に専用のブロックを用意し、決められた要素・レイアウトのブロックしか配置できませんでしたが、Theme Blocksであればブロックの中身を任意のパーツで構成できるため、同じセクションでも用途に合わせて様々な見せ方が可能になりました。

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション
比較的柔軟に対応できるマルチカラムセクションも、ブロックのレイアウトが固定なためバリエーションが出しづらい
【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション
Theme Blocksを使用したマルチカラムセクションと同様のレイアウト。同じ3カラム構成だが、各カラム毎にコンテンツを変えることが可能。

2.2 既存セクションの課題

Shopifyのカスタマイズ機能はノーコードでセクションを追加したりテキストを変更できるため便利であるものの、フロントエンド開発視点で見ると同じ様なレイアウトでもコンテンツの中身が少し異なるだけで都度専用のセクションを開発する必要があり、個人的には非常に非効率な印象がありました。

例えば次の様な分割レイアウトのデザインがあった場合、「CHARACTERISTIC」エリアの3カラム部分と、「BUSINESS」エリアの分割カラム部分は装飾的な見た目は確かに異なりますが、構造的に分解してみるとどちらもほぼ同じ構成であることがわかります。(画像上に見出しがあるかないかの違いだけ)

Shopifyでこのデザインをセクション化する場合、通常であれば別レイアウトになるためこの見出し1つの違いのためにそれぞれセクションを用意する形になるかと思います。

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション

またShopifyではセクション単位でのコンテンツ配置となるため、こちらの様にセクションを跨いだ背景設定が困難といった点も、微妙な差異による不要なセクション開発の要因となっていると感じています。

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション
専用セクションを用意しない限り、上記の様な背景設定が実現できない。(赤線と黄色線を含めた大きなセクションが必要となる)

2.3 Shopify Theme Blocksでやってみたいこと

Shopify Theme Blocksを利用すれば、コンテンツの差異の解消・グループ化が実現できるため、以下の様に様々なレイアウトも1つのセクションで再現できる可能性があります。

今回はこちらの様なレイアウトを1セクションで実装みたいと思います。

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション

開発コードサンプル

万能セクションのサンプルコードです。 一部アレンジを加えていますが、Dawnのgrid思想に構造を合わせています。 ※CSSは適宜調整してください。

3.1 パーツの作成

パーツはグループ要素を含めて、全部で6種類用意しました。今後増える可能性もありますが、以下のパーツで大体のものには対応できるかと思います。 以下を「blocks」ディレクトリに配置します。

ファイル用途
custom-contentsgroup-multicolumn.liquidグループ用のパーツ
custom-contents-heading.liquid見出し用のパーツ
custom-contents-text.liquidテキスト用のパーツ
custom-contents-image.liquid画像用のパーツ
custom-contents-button.liquidボタン(リンク)用のパーツ
custom-contents-liquid.liquidスクリプト用のパーツ

custom-contentsgroup-multicolumn.liquid

<div class="custom-blocks-group {{ block.settings.group_id }} grid {{ block.settings.column_gap }} {{ block.settings.column_grid }} {{ block.settings.column_grid_sp }} align-{{ block.settings.alignment }} valign-{{ block.settings.valignment }}" data-group-label="{{ block.settings.group_name }}" data-group-id="{{ block.settings.group_id }}">
  {% content_for 'blocks' %}
</div>

{% schema %}
{
  "name": "Group(マルチカラム)",
  "class": "group__item grid__item",
  "blocks": [
    { "type": "custom-contentsgroup-multicolumn" },
    { "type": "custom-contents-heading" },
    { "type": "custom-contents-text" },
    { "type": "custom-contents-image" },
    { "type": "custom-contents-button" },
    { "type": "custom-contents-liquid" },
    { "type": "@app" }
  ],
  "settings": [
    {
      "type": "text",
      "id": "group_id",
      "label": "グループの追加クラス",
    },
    {
      "type": "select",
      "id": "column_grid",
      "options": [
        {
          "value": "grid--1-col",
          "label": "1列"
        },
        {
          "value": "grid--2-col",
          "label": "2列"
        },
        {
          "value": "grid--3-col",
          "label": "3列"
        },
        {
          "value": "grid--4-col",
          "label": "4列"
        },
        {
          "value": "grid--5-col",
          "label": "5列"
        },
        {
          "value": "grid--6-col",
          "label": "6列"
        },
      ],
      "default": "grid--5-col",
      "label": "デスクトップの列数"
    },
    {
      "type": "select",
      "id": "column_grid_sp",
      "options": [
        {
          "value": "grid--1-col-tablet",
          "label": "1列"
        },
        {
          "value": "grid--2-col-tablet",
          "label": "2列"
        },
      ],
      "default": "grid--2-col-tablet",
      "label": "モバイルでの列数"
    },
    {
      "type": "select",
      "id": "column_gap",
      "options": [
        {
          "value": "grid--gapless",
          "label": "余白なし"
        },
        {
          "value": "grid--gap-xs",
          "label": "最小"
        },
        {
          "value": "grid--gap-s",
          "label": "狭い"
        },
        {
          "value": "grid--gap-def",
          "label": "通常"
        },
        {
          "value": "grid--gap-l",
          "label": "広い"
        },
      ],
      "default": "grid--gap-def",
      "label": "カラム間の余白"
    },
    {
      "type": "text_alignment",
      "id": "alignment",
      "label": "カラムの配置"
    },
    {
      "type": "select",
      "id": "valignment",
      "options": [
        {
          "value": "top",
          "label": "上寄せ"
        },
        {
          "value": "center",
          "label": "中央寄せ"
        }
      ],
      "default": "top",
      "label": "上寄せ"
    },
  ],
  "presets": [
    {
      "name": "Group(マルチカラム)"
    }
  ]
}
{% endschema %}

custom-contents-heading.liquid

<{{ block.settings.heading_type }} class="title align-{{ block.settings.alignment }} size-{{ block.settings.heading_size }} {{ block.settings.item_class }}">{{ block.settings.heading }}</{{ block.settings.heading_type }}>
{% schema %}{"name":"見出し","class":"blocks__item blocks__item-heading grid__item","settings":[{"type":"text","id":"heading","label":"見出し"},{"type":"select","id":"heading_type","options":[{"value":"h1","label":"h1"},{"value":"h2","label":"h2"},{"value":"h3","label":"h3"},{"value":"h4","label":"h4"},{"value":"h5","label":"h5"},{"value":"p","label":"指定なし"}],"default":"h3","label":"見出しタイプ"},{"type":"select","id":"heading_size","options":[{"value":"xs","label":"最小"},{"value":"s","label":"小"},{"value":"def","label":"標準"},{"value":"m","label":"大"},{"value":"l","label":"特大"},{"value":"xl","label":"最大"}],"default":"m","label":"見出しサイズ"},{"type":"text_alignment","id":"alignment","label":"配置"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"見出し"},]}{% endschema %}

custom-contents-text.liquid

<div class="align-{{ block.settings.alignment }} {{ block.settings.item_class }}">{{block.settings.text}}</div>
{% schema %}{"name":"テキスト","class":"blocks__item blocks__item-text grid__item","settings":[{"type":"richtext","id":"text","label":"Text"},{"type":"text_alignment","id":"alignment","label":"配置"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"テキスト"},]}{% endschema %}

custom-contents-image.liquid

<picture class="image-wrapper {{ block.settings.item_class }}"><img src="{{ block.settings.image | img_url: 'master' }}" loading="lazy"></picture>
{% schema %}{"name":"画像","class":"blocks__item blocks__item-image grid__item","settings":[{"type":"image_picker","id":"image","label":"t:sections.multicolumn.blocks.column.settings.image.label"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"画像"},]}{% endschema %}

custom-contents-button.liquid

<div class="align-{{ block.settings.alignment }} {{ block.settings.item_class }}"><{%- if block.settings.button_link !=blank -%}a{%- else -%}span{% endif %}{%- if block.settings.button_link !=blank -%}href="{{ block.settings.button_link }}"{% endif %}class="button">{{- block.settings.button_label | escape -}}</{%- if block.settings.button_link !=blank -%}a{%- else -%}span{%- endif -%}></div>
{% schema %}{"name":"ボタン","class":"blocks__item blocks__item-button grid__item","settings":[{"type":"text","id":"button_label","default":"詳しくはこちら","label":"t:sections.multicolumn.settings.button_label.label"},{"type":"url","id":"button_link","label":"t:sections.multicolumn.settings.button_link.label"},{"type":"text_alignment","id":"alignment","label":"配置"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"ボタン"},]}{% endschema %}

custom-contents-liquid.liquid

{{section.settings.custom_liquid}}
{% schema %}{"name":"カスタムLiquid","class":"blocks__item blocks__item-liquid grid__item","settings":[{"type":"liquid","id":"custom_liquid","label":"t:sections.custom-liquid.settings.custom_liquid.label","info":"t:sections.custom-liquid.settings.custom_liquid.info"}],"presets":[{"name":"カスタムLiquid"},]}{% endschema %}

3.2 セクションの作成

custom-multicolumn.liquid

<div class="custom-multicolumn {{ section.settings.section_class }} page-width">
  <div class="grid {{ section.settings.column_gap }} {{ section.settings.column_grid }} {{ section.settings.column_grid_sp }} align-{{ section.settings.alignment }} valign-{{ section.settings.valignment }}">
  {% content_for 'blocks' %}
  </div>
</div>

{% schema %}
{
  "name": "マルチカラム(Theme Blocks)",
  "class": "section custom-section-multicolumn",
  "tag": "section",
  "blocks": [
    { "type": "custom-contentsgroup-multicolumn" },
    { "type": "custom-contents-heading" },
    { "type": "custom-contents-text" },
    { "type": "custom-contents-image" },
    { "type": "custom-contents-button" },
    { "type": "custom-contents-liquid" },
    { "type": "@app" }
  ],
  "settings": [
    {
      "type": "text",
      "id": "section_class",
      "label": "セクションの追加class"
    },
    {
      "type": "select",
      "id": "column_grid",
      "options": [
        {
          "value": "grid--1-col",
          "label": "1列"
        },
        {
          "value": "grid--2-col",
          "label": "2列"
        },
        {
          "value": "grid--3-col",
          "label": "3列"
        },
        {
          "value": "grid--4-col",
          "label": "4列"
        },
        {
          "value": "grid--5-col",
          "label": "5列"
        },
        {
          "value": "grid--6-col",
          "label": "6列"
        },
      ],
      "default": "grid--5-col",
      "label": "デスクトップの列数"
    },
    {
      "type": "select",
      "id": "column_grid_sp",
      "options": [
        {
          "value": "grid--1-col-tablet",
          "label": "1列"
        },
        {
          "value": "grid--2-col-tablet",
          "label": "2列"
        },
      ],
      "default": "grid--2-col-tablet",
      "label": "モバイルでの列数"
    },
    {
      "type": "select",
      "id": "column_gap",
      "options": [
        {
          "value": "grid--gapless",
          "label": "余白なし"
        },
        {
          "value": "grid--gap-xs",
          "label": "最小"
        },
        {
          "value": "grid--gap-s",
          "label": "狭い"
        },
        {
          "value": "grid--gap-def",
          "label": "通常"
        },
        {
          "value": "grid--gap-l",
          "label": "広い"
        },
      ],
      "default": "grid--gap-def",
      "label": "カラム間の余白"
    },
    {
      "type": "text_alignment",
      "id": "alignment",
      "label": "カラムの配置"
    },
    {
      "type": "select",
      "id": "valignment",
      "options": [
        {
          "value": "top",
          "label": "上寄せ"
        },
        {
          "value": "center",
          "label": "中央寄せ"
        }
      ],
      "default": "top",
      "label": "上寄せ"
    },
  ],
  "presets": [
    {
      "name": "マルチカラム(Theme Blocks)",
      "blocks": [
        {
          "type": "custom-contentsgroup-multicolumn",
        }
      ]
    }
  ]
}
{% endschema %}

3.3 ポイント解説

custom-contentsgroup-multicolumn.liquid

セクション自体のgrid化はもちろん、グループパーツもgrid化しているのでネストされた中でさらに分割化が可能です。

また各パーツにCSSのクラスを付与できるようにしているため、より細かなデザイン調整が可能です。

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション
3分割した中で、さらに画像を2分割にして表示。グループパーツだけでなく、見出しパーツなどにもCSSクラスの設定が可能に実装。

3.4 実装プレビュー

開発した万能セクションを使って、以下の通り色々なレイアウトパターンを1つのセクションで対応することができました!

【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション
設定画面
【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう - 株式会社テックディレクション
セクション配置後のキャプチャ

まとめ

Shopify Theme Blocksの活かし方についてイメージ湧きましたでしょうか? 今回作成したセクションでも十分マルチに活躍できるかと思いますが、様々なケースに対応する中でより万能セクションへとブラッシュアップしていきたいと思います!

Theme Blocksのカスタマイズについては以下の記事も参考にしてみてください。

Shopify Winter Editions ‘25 | 冬のアップデート2025:Theme Blocksと今後のテーマ開発の動向

Shopify Winter Editions ‘25 | 冬のアップデート2025:Theme Blocksについて第二部:Theme Blocksの基本構成

Shopify Winter ’25 Theme Blocks 応用編(第三部):ターゲティング&Static Blocks徹底解説

著者:T.O

弊社では、ECサイトのリプレース案件から、Shopifyカスタムアプリ開発、保守案件に至るまで、EC中心にプロジェクトの質にこだわり、お客様に笑顔になってもらえるよう日々邁進しております。

皆様からのお問い合わせ・ご相談をお待ちしております。

コメントはこちら