CUSTOM SIZE OPTION

Topic summary

A Shopify developer is implementing a custom size option on product pages without third-party apps. The requirement includes:

Core Functionality:

  • Size dropdown (S, M, L, etc.) with “Custom” option
  • When “Custom” is selected, display a form for measurements (shoulder, bust, waist, hip, height)
  • Submit measurements as line item properties with the order

Solutions Provided:

Approach 1 (TheUntechnickle): Custom Liquid + JavaScript code snippet that:

  • Adds “Custom” to size dropdown
  • Shows/hides measurement form based on selection
  • Captures data as line item properties
  • Includes styling suggestions and optional measurement guide

Approach 2 (tim_1): “Custom liquid” block method using CSS selectors to show/hide input fields when specific variant is selected

Current Status:

  • Initial implementations didn’t work due to incorrect CSS selectors
  • Issue resolved: CSS needed to target [value="Custom"] instead of [value="Original"]
  • New requirement emerged: Client needs ~10 input fields in a popup form (similar to reference website)
  • This popup approach acknowledged as “more complex” than current solutions

Open Question: How to implement a modal/popup form for multiple custom measurements instead of inline fields.

Summarized with AI on October 28. AI used: claude-sonnet-4-5-20250929.

Hi everyone,

I’m working on a client project and need help setting up a custom size option directly on the product page — without using any third-party app.

Here’s what we want:

  1. A dropdown for size options (S, M, L, etc.), with “Custom” as one of the choices.
    When a customer selects “Custom” from the dropdown, a form should pop up or appear on the page.
    The form would allow them to fill in basic measurements (e.g., shoulder, bust, waist, hip, height).
    These measurements should be submitted along with the product (likely as line item properties).

Is there a recommended way to implement this using custom Liquid in a Shopify theme? Has anyone done this before or can share a starting point?

Thanks so much in advance!

Hey @snk729 ,

I’ve actually done this for a few clients before, so I’d be happy to share my approach!

This is totally doable with some custom Liquid code and JavaScript. I’ve attached a code snippet below that should give you a solid starting point.

Basically, what this does is:

  • Adds “Custom” as an option in your size dropdown
  • Shows a measurement form when “Custom” is selected
  • Captures those measurements as line item properties that show up in the order
{% comment %}
  Add this code to your product-template.liquid file where your variant selection appears
{% endcomment %}

<div class="product-form">
  {% form 'product', product %}
    <select name="id" id="ProductSelect" class="product-form__variants">
      {% for variant in product.variants %}
        {% if variant.available %}
          <option value="{{ variant.id }}">
            {{ variant.title }} - {{ variant.price | money }}
          </option>
        {% else %}
          <option disabled="disabled">
            {{ variant.title }} - Sold Out
          </option>
        {% endif %}
      {% endfor %}
    </select>

    {% comment %}
      Size selector - Assumes you have a variant option called "Size"
      Make sure to adjust based on how your variants are set up
    {% endcomment %}
    {% if product.options_by_name['Size'] %}
      <div class="size-selector">
        <label for="Size">Size</label>
        <select name="options[Size]" id="SizeSelector">
          {% for value in product.options_by_name['Size'].values %}
            <option value="{{ value }}">{{ value }}</option>
          {% endfor %}
          <option value="Custom">Custom</option>
        </select>
      </div>
    {% endif %}

    {% comment %} Custom size form that will appear when "Custom" is selected {% endcomment %}
    <div id="custom-size-form" style="display: none;">
      <h3>Enter Your Custom Measurements</h3>
      <div class="measurement-fields">
        <div class="measurement-field">
          <label for="measurement-shoulder">Shoulder (inches)</label>
          <input type="number" id="measurement-shoulder" name="properties[Shoulder]" step="0.1">
        </div>
        <div class="measurement-field">
          <label for="measurement-bust">Bust (inches)</label>
          <input type="number" id="measurement-bust" name="properties[Bust]" step="0.1">
        </div>
        <div class="measurement-field">
          <label for="measurement-waist">Waist (inches)</label>
          <input type="number" id="measurement-waist" name="properties[Waist]" step="0.1">
        </div>
        <div class="measurement-field">
          <label for="measurement-hip">Hip (inches)</label>
          <input type="number" id="measurement-hip" name="properties[Hip]" step="0.1">
        </div>
        <div class="measurement-field">
          <label for="measurement-height">Height (inches)</label>
          <input type="number" id="measurement-height" name="properties[Height]" step="0.1">
        </div>
      </div>
    </div>

    <button type="submit" name="add" id="AddToCart" class="btn">
      <span id="AddToCartText">Add to Cart</span>
    </button>
  {% endform %}
</div>

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var sizeSelector = document.getElementById('SizeSelector');
    var customSizeForm = document.getElementById('custom-size-form');
    
    // Function to toggle custom size form visibility
    function toggleCustomSizeForm() {
      if (sizeSelector.value === 'Custom') {
        customSizeForm.style.display = 'block';
      } else {
        customSizeForm.style.display = 'none';
      }
    }
    
    // Add event listener to size selector
    if (sizeSelector) {
      sizeSelector.addEventListener('change', toggleCustomSizeForm);
      
      // Check initial state
      toggleCustomSizeForm();
    }
    
    // Validate before form submission
    document.querySelector('form[action="/cart/add"]').addEventListener('submit', function(e) {
      if (sizeSelector && sizeSelector.value === 'Custom') {
        // Simple validation for custom measurements
        var allFieldsFilled = true;
        var measurementFields = document.querySelectorAll('#custom-size-form input[type="number"]');
        
        measurementFields.forEach(function(field) {
          if (!field.value || field.value.trim() === '') {
            allFieldsFilled = false;
          }
        });
        
        if (!allFieldsFilled) {
          e.preventDefault();
          alert('Please fill in all measurement fields for custom sizing.');
        }
      }
    });
  });
</script>

<style>
  #custom-size-form {
    margin: 20px 0;
    padding: 15px;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    background: #f9f9f9;
  }
  
  .measurement-fields {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 15px;
    margin-top: 15px;
  }
  
  .measurement-field {
    display: flex;
    flex-direction: column;
  }
  
  .measurement-field label {
    margin-bottom: 5px;
    font-size: 14px;
  }
  
  .measurement-field input {
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
  }
</style>

You’ll need to tweak this a bit depending on your theme structure, but the general approach should work well. It’s easy to customize - just add/remove measurement fields as needed and adjust the styling to match your store’s design.

For one client, I also added a “measurement guide” with illustrations showing customers exactly where to measure, which helped reduce errors. Just a thought if that might be useful for your project too.

Let me know if you have any questions or run into any issues implementing this! Happy to help troubleshoot if needed.

Best regards,
Shubham | Untechnickle

Yes, of course, you can do that with “Custom liquid” block. Here is the quick and dirty example: https://ye3i08yg3v4seadq-23104437.shopifypreview.com/products/absolut-vodka-700ml?variant=31297174470710

When you switch to “Original” the inputs are shown.

The “Custom liquid” is added right after the “Variant selects” (this is important) and the content is this:


  

    
  

  

    
  

Updated – added some JS to avoid LIPs passing when hidden.

Hi All - thanks for the help! I tried these solutions - but somehow still did not work - i added the sizes as variants - some said to add them as category metafields.. not sure what to do? can i share the unpublished website url here for help?

password:
[email removed]

Hi All - thanks for the help! I tried these solutions - but somehow still did not work - i added the sizes as variants - some said to add them as category metafields.. not sure what to do? can i share the unpublished website url here for help?

password:
mahru@123

Of course it would not – I had no idea how your option is actually called and the code was for my test store, where it worked flawlessly.

For you store the CSS part of the code should be


See the selector variant-selects:has([value=“Custom”][selected]) + .lips ?

This means the rule will apply to the .lips element which is placed directly after variant-selects where option with value=“Custom” is selected – basically rule means that if “Custom” is selected in drop-down, show the extra input fields.

For my demo it had [value=“Original”] – meaning extra fields were shown only for Original variant of the product, that’s why it did not work for your store.

the client requires a lot of input options (around 10) - is there a way to make it a form? like how this website has it - https://www.indyverse.in/product/moon-white-embroidered-kurta-dress-iv-rsd-00014

basically when the user selects CUSTOM from the dropdown the pop up comes with the form

That would be more complex.

You cans still add more inputs to the code suggested.