How can I reorder size filters on my website?

Topic summary

A user is experiencing an issue with size filter ordering on their Shopify store. The filters currently display randomly instead of in the desired sequence (XS, S, M, L, XL, 2XL - or XCH, CH, M, G, XG, 2XG in Spanish).

Attempted Solution:
They tried using a jQuery script to reorder the filters, which works on initial page load but breaks when users interact with filters—causing the random order to return.

Proposed Workaround:
Another user (calebstephen) suggests creating a variant metafield with a list of specified values that can be manually ordered, then adding the appropriate value to each variant. They acknowledge this is a workaround rather than a definitive solution.

Current Status:
The original poster is interested in this approach and has asked for clarification on how to associate the metafields to each variant as filters. The discussion remains open with no confirmed resolution yet.

Summarized with AI on November 24. AI used: claude-sonnet-4-5-20250929.

Hello!

What is the best way to re-order size filters? They are current randomly ordered, and I would want to order them in normal sizing order: XS, S, M, L, XL, 2XL.

I tried the following script:

<script async>
jQuery(document).ready(function($) {

$(".size-all").after($(".size-2XG")).after($(".size-XG")).after($(".size-G")).after($(".size-M")).after($(".size-CH")).after($(".size-XCH"));
});
</script>

which works but only on load. If a user selects a filter, the size filters appear in a random order again. (not that XCH, CH, M G, XG, 2XG is in Spanish).

Here’s the current filter-dynamic.liquid code:

{% comment %} ACID POP CUSTOM CSS {% endcomment %}

<div class="widget-title" style="background-color: #F2F3F4">
<h3 class="sidebar-title">Filtros</h3>
</div>
                          
<div class="sidebar-filter" data-has-collapse>
  {% if settings.category_layout == "right_sidebar" or settings.category_layout == "express_order" or template.suffix == 'express-order' or settings.category_layout == "mansory" or template.suffix == 'mansory' or settings.category_layout == "full_with" or template.suffix == 'fullwidth' or template.suffix == 'right-sidebar' or settings.category_layout == "with_banner" or template.suffix == 'with-banner' %}
  <a href="javascript&colon;void(0)" title="{{ 'cart.general.close_cart' | t }}" class="close-sidebar close">
    {% render 'icon-close' %}    
  </a>
  {% endif %}

  <div class="refined-widgets js-filter" data-index="0">
    {% liquid
                      for filter in collection.filters
                        assign total_active_values = total_active_values | plus: filter.active_values.size
                        if filter.min_value.value != blank or filter.max_value.value != blank
                          if filter.min_value.value > 0 or filter.max_value.value < filter.range_max
                            assign total_active_values = 1
                            break
                          endif
                        endif
                      endfor
                    %}
    {% if total_active_values > 0 %}
    <div class="widget-title">
      <h3 class="sidebar-title">
        <span>
          {{ 'collections.sidebar.refined_by' | t }}           
        </span>
        <a href="{{ collection.url }}?sort_by={{ sort_by }}" class="clear-all text-hover active-facets__button button button--secondary js-facet-remove" {% if total_active_values == 0 %}style="display:none"{% endif %}>
          {{ 'collections.sidebar.clear_all' | t }}
        </a>
      </h3>
    </div>
    <div class="widget-content {{ total_active_values }}">
      <ul class="refined">
        {%- for filter in collection.filters -%}
        {%- for value in filter.active_values -%}
        <li>
          <a class="active-facets__button active-facets__button--light button button--tertiary js-facet-remove" href="{{ value.url_to_remove }}">
            {{ value.label | escape }}
            <svg xmlns="http://www.w3.org/2000/svg" fill="#000000" viewBox="0 0 48 48" width="144px" height="144px"><path d="M 38.982422 6.9707031 A 2.0002 2.0002 0 0 0 37.585938 7.5859375 L 24 21.171875 L 10.414062 7.5859375 A 2.0002 2.0002 0 0 0 8.9785156 6.9804688 A 2.0002 2.0002 0 0 0 7.5859375 10.414062 L 21.171875 24 L 7.5859375 37.585938 A 2.0002 2.0002 0 1 0 10.414062 40.414062 L 24 26.828125 L 37.585938 40.414062 A 2.0002 2.0002 0 1 0 40.414062 37.585938 L 26.828125 24 L 40.414062 10.414062 A 2.0002 2.0002 0 0 0 38.982422 6.9707031 z"/></svg>
          </a>
        </li>
        {%- endfor -%}

        {% if filter.type == "price_range" %}

        {% if filter.min_value.value > 0 or filter.max_value.value < filter.range_max %}
        {%- if filter.min_value.value != nil and filter.max_value.value != nil -%}
        <li class="{{filter.max_value.value}}-{{filter.range_max}}">
          <a class="active-facets__button active-facets__button--light button button--tertiary js-facet-remove" href="{{ filter.url_to_remove }}">
            {%- if filter.min_value.value -%}{{ filter.min_value.value | money }}{%- else -%}{{ 0 | money }}{%- endif -%}-{%- if filter.max_value.value -%}{{ filter.max_value.value | money }}{%- else -%}{{ filter.range_max | money }}{%- endif -%}
            <svg xmlns="http://www.w3.org/2000/svg" fill="#000000" viewBox="0 0 48 48" width="144px" height="144px"><path d="M 38.982422 6.9707031 A 2.0002 2.0002 0 0 0 37.585938 7.5859375 L 24 21.171875 L 10.414062 7.5859375 A 2.0002 2.0002 0 0 0 8.9785156 6.9804688 A 2.0002 2.0002 0 0 0 7.5859375 10.414062 L 21.171875 24 L 7.5859375 37.585938 A 2.0002 2.0002 0 1 0 10.414062 40.414062 L 24 26.828125 L 37.585938 40.414062 A 2.0002 2.0002 0 1 0 40.414062 37.585938 L 26.828125 24 L 40.414062 10.414062 A 2.0002 2.0002 0 0 0 38.982422 6.9707031 z"/></svg>
          </a>
        </li>
        {%- endif -%}
        {%- endif -%}

        {% endif %}
        {%- endfor -%}
      </ul>
    </div>
    {% endif %}           
  </div>

  {% if collection.current_vendor or collection.current_type %}
  <input type="hidden" name="q" value="{{ collection.current_vendor }}{{ collection.current_type }}">
  {% endif %}
  {%- for filter in collection.filters -%}
  
  {%- assign total_active_values = total_active_values | plus: filter.active_values.size -%}
  {% case filter.type %}
  {% when 'list' %}
  
  <div class="js-filter widget sidebar-tags {% if style_color contains filter.label %}filter-color{% endif %} {% if style_size contains filter.label %}filter-size{% endif %}" data-index="{{ forloop.index }}">
    <div class="widget-title {% if block.settings.number_collapse < forloop.index %}open{% endif %}">
      <h3 class="sidebar-title">
        <span>{{ filter.label | escape }}</span>
      </h3>
    </div>
    <div class="widget-content" {% if block.settings.number_collapse < forloop.index %}style="display: none"{% endif %}>
      <ul class="list-tags">
        <li class="{% if style_size contains filter.label %}size-all{% endif %}{% unless current_tags %} active{% endunless %}" style="margin-right: 0px; padding:0px;"></li> 
        {%- for value in filter.values-%}
        {% assign tag = value.value | strip %}
        {% assign tag_value = tag | handleize %}

        <li class="white list-menu__item facets__item {% if style_size contains filter.label %}size-{{tag}} {% else %}filter-{{tag}}{% endif %}" {% if forloop.index > 10 %}style="display: none"{% endif %}>
       
          <input type="checkbox"
                 name="{{ value.param_name }}"
                 value="{{ value.value }}"
                 id="Filter-{{ filter.label | escape }}-{{ forloop.index }}"
                 {% if value.active %}checked{% endif %}
                 {% if value.count == 0 and value.active == false %}disabled{% endif %}
                 >
         
          {% if style_color contains filter.label %}
          <label for="Filter-{{ filter.label | escape }}-{{ forloop.index }}" class="facet-checkbox{% if value.count == 0 and value.active == false %} facet-checkbox--disabled{% endif %} {% if value.count == 0 and value.active %}active{% endif %}" title="{{tag}}"
                 style="background-color: {{ tag_value }}; {% if settings.show_product_color_img %}background-image: url({{ tag_value | handle | append: '.png' | file_url }}){% endif %}">
          </label>
          
          
          {% else %}
          
          <label for="Filter-{{ filter.label | escape }}-{{ forloop.index }}" class="facet-checkbox{% if value.count == 0 and value.active == false %} facet-checkbox--disabled{% endif %}">
           
            {{ value.label | escape }} <span class="count_value">{{ value.count }}</span>
        
          </label>
          {% endif %}
         
  
        </li>
     

        {% if forloop.index == 11 %}
        <li class="show-more--list_tags">
          <span class="icon">
            <svg id="Solid" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m192 424a23.928 23.928 0 0 1 -16.971-7.029l-144-144a24 24 0 0 1 0-33.942l144-144a24 24 0 0 1 33.942 33.942l-127.03 127.029 127.03 127.029a24 24 0 0 1 -16.971 40.971zm144.971-7.029 144-144a24 24 0 0 0 0-33.942l-144-144a24 24 0 0 0 -33.942 33.942l127.03 127.029-127.03 127.029a24 24 0 0 0 33.942 33.942z"/></svg>
          </span>
          {{ 'general.sidebar.more' | t }}
        </li>
        {% endif %}

        {% endfor %}

        {%- for option in collection.sort_options -%}
        {% if option.value == sort_by %}
        <input type="radio" id="{{ option.value }}" name="sort_by" value="{{ option.value }}" {% if option.value == sort_by %}checked{% endif %} style="display: none;">
        {% endif %}
        {% endfor %}

      </ul>
    </div>
  </div>
  {% when 'price_range' %}
  {% liquid
    assign currencies_using_comma_decimals = 'ANG,ARS,BRL,BYN,BYR,CLF,CLP,COP,CRC,CZK,DKK,EUR,HRK,HUF,IDR,ISK,MZN,NOK,PLN,RON,RUB,SEK,TRY,UYU,VES,VND' | split: ','
    assign uses_comma_decimals = false
    if currencies_using_comma_decimals contains cart.currency.iso_code
      assign uses_comma_decimals = true
    endif
  %}
  <div class="js-filter widget sidebar-tags" data-index="{{ forloop.index }}">
    <div class="widget-title {% if block.settings.number_collapse < forloop.index %}open{% endif %}">
      <h3 class="sidebar-title">
        <span>{{ filter.label | escape }}</span>
      </h3>
    </div>

    <div class="widget-content" {% if block.settings.number_collapse < forloop.index %}style="display: none"{% endif %}>
      <price-range class="facets__price">
        <div class="range_price--box">
          <div class="price-slider">
            <div class="box-slide">
              <label>
                <span class="field__currency">{{ cart.currency.symbol }}</span>
                <input class="field__input filter__price filter__min"
                       name="{{ filter.min_value.param_name }}"
                       id="Filter-{{ filter.label | escape }}-{{ forloop.index }}"
                       {%- if filter.min_value.value -%}
                       {%- if uses_comma_decimals -%}
                       value="{{ filter.min_value.value | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', ''  }}"
                       {%- else -%}
                       value="{{ filter.min_value.value | money_without_currency | replace: ',', '' | replace: '.00', '' }}"
                       {% endif %}
                       {%- endif -%}
                       type="number"
                       value="0"
                       min="0"
                       {% if uses_comma_decimals %}
                       max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', '' }}"
                       {% else %}
                       max="{{ filter.range_max | money_without_currency | replace: ',', '' | replace: '.00', ''  }}"
                       {% endif %} />
              </label>
            <span class="slide_price--to">to</span>
            <label>
              <span class="field__currency">{{ cart.currency.symbol }}</span>
              <input class="field__input filter__price filter__max"
                     name="{{ filter.max_value.param_name }}"
                     id="Filter-{{ filter.label | escape }}-{{ forloop.index }}"
                     {%- if filter.max_value.value -%}
                     {%- if uses_comma_decimals -%}
                     value="{{ filter.max_value.value | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', '' }}"
                     {%- else -%}
                     value="{{ filter.max_value.value | money_without_currency | replace: ',', '' | replace: '.00', '' }}"
                     {% endif %}
                     {%- else -%}
                     {%- if uses_comma_decimals -%}
                     value="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', ''  }}"
                     {% else %}
                     value="{{ filter.range_max | money_without_currency | replace: ',', '' | replace: '.00', ''  }}"
                     {% endif %}
                     {%- endif -%}
                     type="number"
                     min="0"
                     {%- if uses_comma_decimals -%}
                     max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', ''  }}"
                     {%- else -%}
                     max="{{ filter.range_max | money_without_currency | replace: ',', '' | replace: '.00', ''  }}"
                     {% endif %} />
            </label>
        </div>
        <label class="apply__button" for="apply__button--price">
          <input class="apply__button--price" type="checkbox" id="apply__button--price" />
          {{ 'cart.general.apply' | t }}
        </label>
        <input min="0" 
               {%- if uses_comma_decimals -%}
               max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', ''  }}"
               {%- else -%}
               max="{{ filter.range_max | money_without_currency | replace: ',', '' | replace: '.00', ''  }}"
               {% endif %}
               step="1" type="range" 
               {%- if filter.min_value.value -%}
               {%- if uses_comma_decimals -%}
               value="{{ filter.min_value.value | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', '' }}"
               {%- else -%}
               value="{{ filter.min_value.value | money_without_currency | replace: ',', '' | replace: '.00', '' }}"
               {% endif %}
               {%- else -%}
               value="0"
               {%- endif -%} />
        <input min="0" 
               {%- if uses_comma_decimals -%}
               max="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', ''  }}"
               {%- else -%}
               max="{{ filter.range_max | money_without_currency | replace: ',', '' | replace: '.00', ''  }}"
               {% endif %} 
               step="1" type="range" 
               {%- if filter.max_value.value -%}
               {%- if uses_comma_decimals -%}
               value="{{ filter.max_value.value | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', '' }}"
               {%- else -%}
               value="{{ filter.max_value.value | money_without_currency | replace: ',', '' | replace: '.00', '' }}"
               {% endif %}
               {%- else -%}
               {%- if uses_comma_decimals -%}
               value="{{ filter.range_max | money_without_currency | replace: '.', '' | replace: ',', '' | replace: '00', ''  }}"
               {% else %}
               value="{{ filter.range_max | money_without_currency | replace: ',', '' | replace: '.00', ''  }}"
               {% endif %}
               {%- endif -%} />
        </div>
    </div>
    </price-range>
</div>
</div>
{% endcase %}
{%- endfor -%}
<noscript>
  <button type="submit" class="facets__button button">{{ 'sections.collection_template.filter_button' | t }}</button>
</noscript>
</div>
<script async>
    jQuery(document).ready(function($) {
      $(".size-all").after($(".size-2XG")).after($(".size-XG")).after($(".size-G")).after($(".size-M")).after($(".size-CH")).after($(".size-XCH"));
    });
</script> 

Thanks!!

Melissa

We created a variant metafield and then set it be a list of specified values, at that point you can easily reorder them. Then added on each variant the appropriate value. It’s a work around for sure but if solved this issue for us.

Hi Calebstephen,

Thanks for this! This might work. How did you add this as filters after associating the metafields to each variant?

Melissa