How to Show All Variants on a Collection Page in Shopify

By following this guide, you’ll easily enhance your Shopify store with variant displays that make shopping more enjoyable for your customers.

Adeel Qayum writer profile picture
By Adeel Qayum
a woman taking a selfie
Edited by Kim Weidemann
Joel Taylor
Fact-check by Joel Taylor

Published November 7, 2024.

A woman pointing at product variants on a collection page

In this post, we take you through the steps to display all product variants on the collection page in your Shopify store. We’ll guide you through the process with clear steps, and by the end, you'll have a beautifully functional page that showcases all your product variants!

» Differentiate between Shopify collections and Shopify product types for optimal information architecture

Adeel Qayum writer profile picture

Meet the Expert

Adeel Qayum is a digital content strategist with over a decade of experience creating effective copy for SaaS and B2B companies. He has a Master's Degree in Digital Marketing and specializes in long-form content creation. Adeel has worked with notable clients like Shopify, Oberlo, and AfterShip.



What to Know Before Showing Variants On Collection Page

  • Metafields: Get familiar with using metafields, which allow you to add extra product details.
  • Theme compatibility: Ensure that your chosen theme supports the display and functionality of product variants. Themes can significantly impact how your variants, such as size or color, are presented to customers.

How Shopify Themes Impact Product Variant Display

The theme you select for your Shopify store plays a vital role in how variants appear. Each theme handles variant displays uniquely, influencing how customers view and choose options like colors or sizes.

Choosing a theme that complements your product presentation is essential for making the shopping experience as smooth as possible.

» Find out how to add, delete, and hide Shopify variant images



Steps to Show Variants on the Shopify Collection Page

You can show all variants on your collection page by tweaking some code in your Shopify theme. Here’s a step-by-step guide to make it easy for you:

1. Navigate to Your Theme Settings

Log into your Shopify admin panel, click Online Store, then Themes.

a screen shot of a web page with the Shopify


2. Open the Code Editor

Click the ellipsis (three dots) on the right of your theme and then click Edit code.

a screenshot of a web page with a green arrow pointing to the top of


3. Find The Correct File

Under Sections, look for main-collection-product-grid.liquid and open it.

a screenshot of a screenshot of a web page with a link highlighted


4. Insert Code to Show All Product Variants

a screenshot of a computer screen with a program running


Look for the <ul> list tag that displays the product grid. Then paste the following code between the <ul> ... </ul> tags:

<ul id="product-grid" data-id="{{ section.id }}" class="
          grid product-grid grid--{{ section.settings.columns_mobile }}-col-tablet-down
          grid--{{ section.settings.columns_desktop }}-col-desktop">
          {%- for product in collection.products -%}
            {% assign lazy_load = false %}
            {%- if forloop.index > 2 -%}
              {%- assign lazy_load = true -%}
            {%- endif -%}
          {% for option in product.options %}
          {% if product.options_by_name['Color'].values == null %}
                <li class="grid__item">
                {% render 'card-product',
                card_product: product,
                product_title: product.title,
                media_aspect_ratio: section.settings.image_ratio,
                show_secondary_image: section.settings.show_secondary_image,
                show_vendor: section.settings.show_vendor,
                show_rating: section.settings.show_rating,
                lazy_load: lazy_load,
                show_quick_add: section.settings.enable_quick_add,
                section_id: section.id
              %}
              </li>
            {% endif %}
      {% if option == 'Color' %}
      {% assign index = forloop.index0 %}
      {% assign colorlist = '' %}
      {% assign color = '' %}
      {% for variant in product.variants %}
      {% capture color %}
      {{ variant.options[index] }}
          {% endcapture %}
          {% unless colorlist contains color %}
            <li class="grid__item">
              {% render 'card-product-variant',
                card_product: variant,
                title: product.title,
                color: color,
                media_aspect_ratio: section.settings.image_ratio,
                show_secondary_image: section.settings.show_secondary_image,
                show_vendor: section.settings.show_vendor,
                show_rating: section.settings.show_rating,
                lazy_load: lazy_load,
                show_quick_add: section.settings.enable_quick_add,
                section_id: section.id
              %}
            </li>
    {% capture tempList %}
      {{colorlist | append: color | append: " " }}
    {% endcapture %}
    {% assign colorlist = tempList %}
    {% endunless %}
    {% endfor %}
  {% endif %}
{% endfor %}
{%- endfor -%}
</ul>

5. Create a Snippet for Displaying Variants

You’ll also have to create another version of the card-product snippet file to display the variant correctly.

a screenshot of a computer screen with a bunch of text on it


In the Snippets folder, create a new file called card-product-variant and add this code:

{% comment %}
  Renders a product variant card
  Accepts:
  - card_product: {Object} Product Liquid object (optional)
  - media_aspect_ratio: {String} Size of the product image card. Values are "square" and "portrait". Default is "square" (optional)
  - show_secondary_image: {Boolean} Show the secondary image on hover. Default: false (optional)
  - show_vendor: {Boolean} Show the product vendor. Default: false
  - show_rating: {Boolean} Show the product rating. Default: false
  - extend_height: {Boolean} Card height extends to available container space. Default: true (optional)
  - lazy_load: {Boolean} Image should be lazy loaded. Default: true (optional)
  - show_quick_add: {Boolean} Show the quick add button.
  - section_id: {String} The ID of the section that contains this card.
  - horizontal_class: {Boolean} Add a card--horizontal class if set to true. 
efault: false
  - title: product.title
  Usage:
  {% render 'card-product-variant', show_vendor: section.settings.show_vendor %}
{% endcomment %}
{{ 'component-rating.css' | asset_url | stylesheet_tag }}
{%- if card_product and card_product != empty -%}
  {%- liquid
    assign ratio = 1
    if card_product.featured_media and media_aspect_ratio == 'portrait'
      assign ratio = 0.8
    elsif card_product.featured_media and media_aspect_ratio == 'adapt'
      assign ratio = card_product.featured_media.aspect_ratio
    endif
    if ratio == 0 or ratio == nil
      assign ratio = 1
    endif
  -%}
  <div class="card-wrapper product-card-wrapper underline-links-hover">
    <div
      class="
        card
        card--{{ settings.card_style }}
        {% if card_product.featured_media %} card--media{% else %} card--text{% endif %}
        {% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
        {% if extend_height %} card--extend-height{% endif %}
        {% if card_product.featured_media == nil and settings.card_style == 'card' %} ratio{% endif %}
        {% if horizontal_class %} card--horizontal{% endif %}
      "
      style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
    >
      <div
        class="card__inner {% if settings.card_style == 'standard' %}color-{{ settings.card_color_scheme }} gradient{% endif %}{% if card_product.featured_media or settings.card_style == 'standard' %} ratio{% endif %}"
        style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
      >
        {%- if card_product.featured_media -%}
          <div class="card__media">
            <div class="media media--transparent media--hover-effect">
              {% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
              <img
                srcset="
                  {%- if card_product.featured_media.width >= 165 -%}{{ card_product.featured_media | image_url: width: 165 }} 165w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 360 -%}{{ card_product.featured_media | image_url: width: 360 }} 360w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 533 -%}{{ card_product.featured_media | image_url: width: 533 }} 533w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 720 -%}{{ card_product.featured_media | image_url: width: 720 }} 720w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 940 -%}{{ card_product.featured_media | image_url: width: 940 }} 940w,{%- endif -%}
                  {%- if card_product.featured_media.width >= 1066 -%}{{ card_product.featured_media | image_url: width: 1066 }} 1066w,{%- endif -%}
                  {{ card_product.featured_media | image_url }} {{ card_product.featured_media.width }}w
                "
                src="{{ card_product.featured_media | image_url: width: 533 }}"
                sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
                alt="{{ card_product.featured_media.alt | escape }}"
                class="motion-reduce"
                {% unless lazy_load == false %}
                  loading="lazy"
                {% endunless %}
                width="{{ card_product.featured_media.width }}"
                height="{{ card_product.featured_media.height }}"
              >
              {% comment %}theme-check-enable ImgLazyLoading{% endcomment %}
              {%- if card_product.media[1] != nil and show_secondary_image -%}
                <img
                  srcset="
                    {%- if card_product.media[1].width >= 165 -%}{{ card_product.media[1] | image_url: width: 165 }} 165w,{%- endif -%}
                    {%- if card_product.media[1].width >= 360 -%}{{ card_product.media[1] | image_url: width: 360 }} 360w,{%- endif -%}
                    {%- if card_product.media[1].width >= 533 -%}{{ card_product.media[1] | image_url: width: 533 }} 533w,{%- endif -%}
                    {%- if card_product.media[1].width >= 720 -%}{{ card_product.media[1] | image_url: width: 720 }} 720w,{%- endif -%}
                    {%- if card_product.media[1].width >= 940 -%}{{ card_product.media[1] | image_url: width: 940 }} 940w,{%- endif -%}
                    {%- if card_product.media[1].width >= 1066 -%}{{ card_product.media[1] | image_url: width: 1066 }} 1066w,{%- endif -%}
                    {{ card_product.media[1] | image_url }} {{ card_product.media[1].width }}w
                  "
                  src="{{ card_product.media[1] | image_url: width: 533 }}"
                  sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
                  alt=""
                  class="motion-reduce"
                  loading="lazy"
                  width="{{ card_product.media[1].width }}"
                  height="{{ card_product.media[1].height }}"
                >
              {%- endif -%}
            </div>
          </div>
        {%- endif -%}
        <div class="card__content">
          <div class="card__information">
            <h3
              class="card__heading"
              {% if card_product.featured_media == nil and settings.card_style == 'standard' %}
                id="title-{{ section_id }}-{{ card_product.id }}"
              {% endif %}
            >
              <a
                href="{{ card_product.url }}"
                id="StandardCardNoMediaLink-{{ section_id }}-{{ card_product.id }}"
                class="full-unstyled-link"
                aria-labelledby="StandardCardNoMediaLink-{{ section_id }}-{{ card_product.id }} NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}"
              >
                    {{ title | escape }} - {{color}}
              </a>
            </h3>
          </div>
          <div class="card__badge {{ settings.badge_position }}">
            {%- if card_product.available == false -%}
              <span
                id="NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}"
                class="badge badge--bottom-left color-{{ settings.sold_out_badge_color_scheme }}"
              >
                {{- 'products.product.sold_out' | t -}}
              </span>
            {%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}
              <span
                id="NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}"
                class="badge badge--bottom-left color-{{ settings.sale_badge_color_scheme }}"
              >
                {{- 'products.product.on_sale' | t -}}
              </span>
            {%- endif -%}
          </div>
        </div>
      </div>
      <div class="card__content">
        <div class="card__information">
          <h3
            class="card__heading{% if card_product.featured_media or settings.card_style == 'standard' %} h5{% endif %}"
            {% if card_product.featured_media or settings.card_style == 'card' %}
              id="title-{{ section_id }}-{{ card_product.id }}"
            {% endif %}
          >
            <a
              href="{{ card_product.url }}"
              id="CardLink-{{ section_id }}-{{ card_product.id }}"
              class="full-unstyled-link"
              aria-labelledby="CardLink-{{ section_id }}-{{ card_product.id }} Badge-{{ section_id }}-{{ card_product.id }}"
            >
                {{ title | escape }} - {{color}}
            </a>
          </h3>
          <div class="card-information">
            {%- if show_vendor -%}
              <span class="visually-hidden">{{ 'accessibility.vendor' | t }}</span>
              <div class="caption-with-letter-spacing light">{{ card_product.vendor }}</div>
            {%- endif -%}
            <span class="caption-large light">{{ block.settings.description | escape }}</span>
            {%- if show_rating and card_product.metafields.reviews.rating.value != blank -%}
              {% liquid
                assign rating_decimal = 0
                assign decimal = card_product.metafields.reviews.rating.value.rating | modulo: 1
                if decimal >= 0.3 and decimal <= 0.7
                  assign rating_decimal = 0.5
                elsif decimal > 0.7
                  assign rating_decimal = 1
                endif
              %}
              <div
                class="rating"
                role="img"
                aria-label="{{ 'accessibility.star_reviews_info' | t: rating_value: card_product.metafields.reviews.rating.value, rating_max: card_product.metafields.reviews.rating.value.scale_max }}"
              >
                <span
                  aria-hidden="true"
                  class="rating-star color-icon-{{ settings.accent_icons }}"
                  style="--rating: {{ card_product.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ card_product.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"
                ></span>
              </div>
              <p class="rating-text caption">
                <span aria-hidden="true">
                  {{- card_product.metafields.reviews.rating.value }} /
                  {{ card_product.metafields.reviews.rating.value.scale_max -}}
                </span>
              </p>
              <p class="rating-count caption">
                <span aria-hidden="true">({{ card_product.metafields.reviews.rating_count }})</span>
                <span class="visually-hidden">
                  {{- card_product.metafields.reviews.rating_count }}
                  {{ "accessibility.total_reviews" | t -}}
                </span>
              </p>
            {%- endif -%}
            {% render 'price', product: card_product, price_class: '' %}
          </div>
        </div>
        {%- if show_quick_add -%}
          <div class="quick-add no-js-hidden">
            {%- assign product_form_id = 'quick-add-' | append: section_id | append: card_product.id -%}
            {%- if card_product.variants.size == 1 -%}
              <product-form>
                {%- form 'product', card_product, id: product_form_id, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}
                  <input
                    type="hidden"
                    name="id"
                    value="{{ card_product.selected_or_first_available_variant.id }}"
                    disabled
                  >
                  <button
                    id="{{ product_form_id }}-submit"
                    type="submit"
                    name="add"
                    class="quick-add__submit button button--full-width button--secondary"
                    aria-haspopup="dialog"
                    aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ card_product.id }}"
                    aria-live="polite"
                    data-sold-out-message="true"
                    {% if card_product.selected_or_first_available_variant.available == false %}
                      disabled
                    {% endif %}
                  >
                    <span>
                      {%- if card_product.selected_or_first_available_variant.available -%}
                        {{ 'products.product.add_to_cart' | t }}
                      {%- else -%}
                        {{ 'products.product.sold_out' | t }}
                      {%- endif -%}
                    </span>
                    <span class="sold-out-message hidden">
                      {{ 'products.product.sold_out' | t }}
                    </span>
                    <div class="loading-overlay__spinner hidden">
                      <svg
                        aria-hidden="true"
                        focusable="false"
                        role="presentation"
                        class="spinner"
                        viewBox="0 0 66 66"
                        xmlns="http://www.w3.org/2000/svg"
                      >
                        <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle>
                      </svg>
                    </div>
                  </button>
                {%- endform -%}
              </product-form>
            {%- else -%}
              <modal-opener data-modal="#QuickAdd-{{ card_product.id }}">
                <button
                  id="{{ product_form_id }}-submit"
                  type="submit"
                  name="add"
                  class="quick-add__submit button button--full-width button--secondary"
                  aria-haspopup="dialog"
                  aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ card_product.id }}"
                  data-product-url="{{ card_product.url }}"
                >
                  {{ 'products.product.choose_options' | t }}
                  <div class="loading-overlay__spinner hidden">
                    <svg
                      aria-hidden="true"
                      focusable="false"
                      role="presentation"
                      class="spinner"
                      viewBox="0 0 66 66"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle>
                    </svg>
                  </div>
                </button>
              </modal-opener>
              <quick-add-modal id="QuickAdd-{{ card_product.id }}" class="quick-add-modal">
                <div
                  role="dialog"
                  aria-label="{{ 'products.product.choose_product_options' | t: product_name: card_product.title | escape }}"
                  aria-modal="true"
                  class="quick-add-modal__content global-settings-popup"
                  tabindex="-1"
                >
                  <button
                    id="ModalClose-{{ card_product.id }}"
                    type="button"
                    class="quick-add-modal__toggle"
                    aria-label="{{ 'accessibility.close' | t }}"
                  >
                    {% render 'icon-close' %}
                  </button>
                  <div id="QuickAddInfo-{{ card_product.id }}" class="quick-add-modal__content-info"></div>
                </div>
              </quick-add-modal>
            {%- endif -%}
          </div>
        {%- endif -%}
        <div class="card__badge {{ settings.badge_position }}">
          {%- if card_product.available == false -%}
            <span
              id="Badge-{{ section_id }}-{{ card_product.id }}"
              class="badge badge--bottom-left color-{{ settings.sold_out_badge_color_scheme }}"
            >
              {{- 'products.product.sold_out' | t -}}
            </span>
          {%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}
            <span
              id="Badge-{{ section_id }}-{{ card_product.id }}"
              class="badge badge--bottom-left color-{{ settings.sale_badge_color_scheme }}"
            >
              {{- 'products.product.on_sale' | t -}}
            </span>
          {%- endif -%}
        </div>
      </div>
    </div>
  </div>
{%- else -%}
  <div class="product-card-wrapper card-wrapper underline-links-hover">
    <div
      class="
        card
        card--{{ settings.card_style }}
        card--text
        {% if extend_height %} card--extend-height{% endif %}
        {% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
        {% if card_product.featured_media == nil and settings.card_style == 'card' %} ratio{% endif %}
        {{ horizontal_class }}
      "
      style="--ratio-percent: 100%;"
    >
      <div
        class="card__inner {% if settings.card_style == 'standard' %}color-{{ settings.card_color_scheme }} gradient{% endif %}{% if settings.card_style == 'standard' %} ratio{% endif %}"
        style="--ratio-percent: 100%;"
      >
        <div class="card__content">
          <div class="card__information">
            <h3 class="card__heading">
              <a role="link" aria-disabled="true" class="full-unstyled-link">
                {{ 'onboarding.product_title' | t }}
              </a>
            </h3>
          </div>
        </div>
      </div>
      <div class="card__content">
        <div class="card__information">
          <h3 class="card__heading{% if settings.card_style == 'standard' %} h5{% endif %}">
            <a role="link" aria-disabled="true" class="full-unstyled-link">
              {{ 'onboarding.product_title' | t }}
            </a>
          </h3>
          <div class="card-information">
            {%- if show_vendor -%}
              <span class="visually-hidden">{{ 'accessibility.vendor' | t }}</span>
              <div class="caption-with-letter-spacing light">{{ 'products.product.vendor' | t }}</div>
            {%- endif -%}
            {% render 'price' %}
          </div>
        </div>
      </div>
    </div>
  </div>
{%- endif -%}

6. Save Your Changes

Click "Save" after you have added the code.

After completing these steps, all your product variants are displayed on the collection page.

Simple Sample Data App by Egnition

Need to test different product display options in your Shopify store? Use Simple Sample Data to quickly create a variety of products and variants.



Example of a Successful Variant Display

a woman's underwear page on honeylove website


Honeylove is an example of a store that displays variants on its best sellers' collection page. With images of products at the top and product variants below, the brand makes it easy for customers to see and choose options.

Bestsellers reSort

Organize your Shopify products efficiently and automate merchandising to increase sales.

Sort by real revenue, sales, tags, and more

Customize sorting rules per collection

Push new products up, push out-of-stock items down, and drive growth automatically



Dos and Don'ts When Setting Up Product Variants

Dos:

  • Clarity in variant titles: Use simple titles for each variant to make it easier for customers to find what they want.
  • Keep images updated: Ensure that the photos for your variants are always up to date and accurately represent the products.

Don'ts:

  • Overload with choices: Too many options can overwhelm customers. Strike a balance between offering variety and simplicity.
  • Forget to update inventory: Always keep your variant inventory up to date to avoid frustrating customers with out-of-stock products.

» Find out how Shopify's variant inventory policy impacts your store

Consider using color psychology in your variant images when setting up product variants on Shopify. The right colors can subtly influence customer emotions and preferences, making your products more appealing and memorable.

Show Variants to Improve Customer Experience

Following these steps, you can easily display all product variants on your Shopify collection pages, giving customers a clearer view of their options. This enhances their shopping experience and drives more conversions by making products more accessible to find and select.

Keeping your variant images updated and using themes that support clear display options are crucial to maximizing the benefits of this setup.

» Check out our guide on creating smart collections in Shopify to improve product organization

New to Shopify?

Launch your eCommerce business with Shopify's powerful platform. Get everything you need to create, manage, and scale your online store with ease. Join millions of successful merchants worldwide.

Continuous Innovation

We regularly release new features and improvements based on merchant feedback. Our development roadmap is shaped by your needs, ensuring our Shopify apps evolve with your business.

Expert Support Available

Our dedicated support team is available 24/7/365 to help with any questions about our Shopify apps. Reach us through the support icon in any app or email us at support@egnition.io

Pin It on Pinterest