Size Guide Popup

A size chart popup with a how-to-measure image and a "Not sure which size?" prompt.

One section file Product page, next to the size picker Edit in the theme editor

Important: Before making any changes to your theme, duplicate it in Online Store > Themes so you have a backup.

Fit questions cause hesitation before the sale and returns after it. This section adds a Size guide link that opens your size chart in a popup, with an optional how-to-measure image and a prompt that invites unsure shoppers to ask before they buy.

Preview

What you'll build

Size guide

×
Size Chest Waist
XS 82-86 66-70
S 87-91 71-75
M 92-97 76-81
L 98-104 82-88

Not sure which size?

Tell us your height and usual size and we'll recommend the right fit.

Ask about fit

Preview with the default settings. Colours, text and layout can all be changed in the theme editor.

Install

Add it to your store in 4 steps

  1. 1

    Open your theme code

    In Shopify admin go to Online Store > Themes. Next to the theme you want to edit, click the three dots and choose Edit code.

  2. 2

    Create the section

    In the Sections folder click Add a new section, name it lt-size-guide-popup, delete the placeholder code, paste in the code below and click Save.

  3. 3

    Add it in the theme editor

    Click Customize, go to Products > Default product, click Add section and choose Size guide popup.

  4. 4

    Make it yours

    Change the settings in the sidebar, drag the section where you want it, and click Save.

sections/lt-size-guide-popup.liquid · 215 lines
{%- comment -%}
  Size guide popup with fit-question prompt by LAUNCHTIP
  https://launchtip.com/free-shopify-sections-code
  The size table is written as comma-separated rows. The first row is the header.
{%- endcomment -%}
{%- style -%}
  #lt-{{ section.id }} { padding: {{ section.settings.padding }}px 0; }
  #lt-{{ section.id }} .lt-sg__open { display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; padding: 0; font: inherit; color: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
  #lt-{{ section.id }} .lt-sg__open svg { width: 18px; height: 18px; }
  #lt-{{ section.id }} dialog { width: min(640px, calc(100vw - 32px)); max-height: calc(100vh - 64px); padding: 0; border: 0; border-radius: 12px; box-shadow: 0 20px 60px rgba(0,0,0,0.25); }
  #lt-{{ section.id }} dialog::backdrop { background: rgba(0,0,0,0.5); }
  #lt-{{ section.id }} .lt-sg__inner { padding: 24px; overflow-y: auto; }
  #lt-{{ section.id }} .lt-sg__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
  #lt-{{ section.id }} .lt-sg__head h2 { margin: 0; }
  #lt-{{ section.id }} .lt-sg__close { background: none; border: 0; font-size: 28px; line-height: 1; cursor: pointer; color: inherit; }
  #lt-{{ section.id }} .lt-sg__table-wrap { overflow-x: auto; margin: 14px 0; }
  #lt-{{ section.id }} table { width: 100%; border-collapse: collapse; font-size: 0.92em; }
  #lt-{{ section.id }} th, #lt-{{ section.id }} td { padding: 9px 10px; border-bottom: 1px solid {{ section.settings.border_color }}; text-align: left; white-space: nowrap; }
  #lt-{{ section.id }} th { background: {{ section.settings.header_background }}; }
  #lt-{{ section.id }} .lt-sg__image img { width: 100%; height: auto; border-radius: 8px; }
  #lt-{{ section.id }} .lt-sg__prompt { margin-top: 18px; padding: 16px; border-radius: 10px; background: {{ section.settings.prompt_background }}; }
  #lt-{{ section.id }} .lt-sg__prompt p { margin: 4px 0 12px; }
  #lt-{{ section.id }} .lt-sg__ask { display: inline-block; background: {{ section.settings.button_color }}; color: {{ section.settings.button_text }}; border-radius: 6px; padding: 10px 16px; font-weight: 600; text-decoration: none; }
{%- endstyle -%}

{%- liquid
  assign rows = section.settings.table | newline_to_br | split: '<br />'
  assign ask_link = section.settings.prompt_link | default: '/pages/contact'
  if product != blank and ask_link contains 'mailto:'
    assign ask_subject = 'Sizing question: ' | append: product.title | url_encode
    assign ask_link = ask_link | append: '?subject=' | append: ask_subject
  endif
-%}

<div id="lt-{{ section.id }}" class="page-width">
  <button type="button" class="lt-sg__open" aria-haspopup="dialog">
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/></svg>
    {{ section.settings.link_label }}
  </button>

  <dialog aria-labelledby="lt-{{ section.id }}-title">
    <div class="lt-sg__inner">
      <div class="lt-sg__head">
        <h2 id="lt-{{ section.id }}-title" class="h3">{{ section.settings.heading }}</h2>
        <button type="button" class="lt-sg__close" aria-label="Close">&times;</button>
      </div>
      {%- if section.settings.intro != blank -%}
        <div>{{ section.settings.intro }}</div>
      {%- endif -%}

      <div class="lt-sg__table-wrap">
        <table>
          <thead>
            <tr>
              {%- assign header = rows.first | strip | split: ',' -%}
              {%- for cell in header -%}<th scope="col">{{ cell | strip }}</th>{%- endfor -%}
            </tr>
          </thead>
          <tbody>
            {%- for row in rows offset: 1 -%}
              {%- assign line = row | strip -%}
              {%- if line == blank -%}{%- continue -%}{%- endif -%}
              <tr>
                {%- assign cells = line | split: ',' -%}
                {%- for cell in cells -%}<td>{{ cell | strip }}</td>{%- endfor -%}
              </tr>
            {%- endfor -%}
          </tbody>
        </table>
      </div>

      {%- if section.settings.image != blank -%}
        <div class="lt-sg__image">
          {{ section.settings.image | image_url: width: 1000 | image_tag: loading: 'lazy' }}
        </div>
      {%- endif -%}

      {%- if section.settings.show_prompt -%}
        <div class="lt-sg__prompt">
          <strong>{{ section.settings.prompt_heading }}</strong>
          <p>{{ section.settings.prompt_text }}</p>
          <a class="lt-sg__ask" href="{{ ask_link }}">{{ section.settings.prompt_button }}</a>
        </div>
      {%- endif -%}
    </div>
  </dialog>
</div>

<script>
  (function () {
    var root = document.getElementById('lt-{{ section.id }}');
    if (!root || root.dataset.ready) return;
    root.dataset.ready = '1';

    var dialog = root.querySelector('dialog');
    root.querySelector('.lt-sg__open').addEventListener('click', function () { dialog.showModal(); });
    root.querySelector('.lt-sg__close').addEventListener('click', function () { dialog.close(); });
    dialog.addEventListener('click', function (event) { if (event.target === dialog) dialog.close(); });
  })();
</script>

{% schema %}
{
  "name": "Size guide popup",
  "tag": "section",
  "class": "lt-sg-section",
  "settings": [
    {
      "type": "text",
      "id": "link_label",
      "label": "Link label",
      "default": "Size guide"
    },
    {
      "type": "text",
      "id": "heading",
      "label": "Popup heading",
      "default": "Size guide"
    },
    {
      "type": "richtext",
      "id": "intro",
      "label": "Intro",
      "default": "<p>Measurements are body measurements in centimetres. If you're between sizes, size up for a relaxed fit.</p>"
    },
    {
      "type": "textarea",
      "id": "table",
      "label": "Size table",
      "default": "Size, Chest, Waist, Hips\nXS, 82-86, 66-70, 88-92\nS, 87-91, 71-75, 93-97\nM, 92-97, 76-81, 98-103\nL, 98-104, 82-88, 104-110\nXL, 105-111, 89-95, 111-117",
      "info": "One row per line, cells separated by commas. The first row is the header."
    },
    {
      "type": "image_picker",
      "id": "image",
      "label": "How to measure image"
    },
    {
      "type": "checkbox",
      "id": "show_prompt",
      "label": "Show fit question prompt",
      "default": true
    },
    {
      "type": "text",
      "id": "prompt_heading",
      "label": "Prompt heading",
      "default": "Not sure which size?"
    },
    {
      "type": "text",
      "id": "prompt_text",
      "label": "Prompt text",
      "default": "Tell us your height and usual size and we'll recommend the right fit."
    },
    {
      "type": "text",
      "id": "prompt_button",
      "label": "Prompt button label",
      "default": "Ask about fit"
    },
    {
      "type": "text",
      "id": "prompt_link",
      "label": "Prompt button link",
      "info": "A page URL or mailto: address. Leave blank to use /pages/contact."
    },
    {
      "type": "color",
      "id": "header_background",
      "label": "Table header background",
      "default": "#f5f5f5"
    },
    {
      "type": "color",
      "id": "border_color",
      "label": "Table border colour",
      "default": "#e5e5e5"
    },
    {
      "type": "color",
      "id": "prompt_background",
      "label": "Prompt background",
      "default": "#eef2ff"
    },
    {
      "type": "color",
      "id": "button_color",
      "label": "Button colour",
      "default": "#111111"
    },
    {
      "type": "color",
      "id": "button_text",
      "label": "Button text colour",
      "default": "#ffffff"
    },
    {
      "type": "range",
      "id": "padding",
      "label": "Vertical padding",
      "min": 0,
      "max": 40,
      "step": 2,
      "unit": "px",
      "default": 6
    }
  ],
  "presets": [
    {
      "name": "Size guide popup"
    }
  ]
}
{% endschema %}
Customization

What you can change in the theme editor

Setting Default
Link label Size guide
Popup heading Size guide
Intro Measurements are body measurements in centimetres. If you're between sizes, s...
Size table One row per line, cells separated by commas. The first row is the header. Size, Chest, Waist, Hips XS, 82-86, 66-70, 88-92 S, 87-91, 71-75, 93-97 M, 92...
How to measure image —
Show fit question prompt On
Prompt heading Not sure which size?
Prompt text Tell us your height and usual size and we'll recommend the right fit.
Prompt button label Ask about fit
Prompt button link A page URL or mailto: address. Leave blank to use /pages/contact. —
Table header background #f5f5f5
Table border colour #e5e5e5
Prompt background #eef2ff
Button colour #111111
Button text colour #ffffff
Vertical padding 6px
Good to know

Tips for setting it up

  • Type the size chart one row per line, with cells separated by commas. The first row becomes the header.
  • Create one product template per size chart (for example tops and trousers) so each product shows the right chart.
  • Point the prompt at your contact page, a mailto: link, or your chat widget's page.

Further reading: Add a chatbot to your Shopify store

FAQ

Frequently asked questions

Can I use a different chart for each product?

The chart is set per template. Create a product template for each chart and assign products to it.

Is the popup accessible?

It uses the browser's built-in dialog element, so it traps focus, closes with Escape, and is announced to screen readers.

Can I show inches and centimetres?

Add both as columns, for example Chest (cm), Chest (in).

Chatkit

Want this without the code?

Chatkit answers fit questions in chat using your size charts and product details, any time of day, and passes tricky ones to you.

Try Chatkit

More free sections

New

Order Tracking Help Page

A Track your order page with steps, carrier links, common questions and a help box.

New

Spam-Protected Contact Form

A contact form with a honeypot, a time check and link blocking to stop spam.

Free FAQ Section

Free FAQ Section

Inform customers of store information and policies with this clean FAQ section.

Explore More Free Sections

Discover more code snippets to enhance your Shopify store.

View All Sections
SellUp Increase AOV with Upsells