If you have a product such as a swimsuit that has 10 colors, you may want to keep it as one product, but to make your collection page look more ‘full’, so here is how you can turn that one product into 10 different ones on the collection page, but have the product page stay the same as one product with many variants.
Color variants can be displayed as separate products on the collection page by Shopify. Customers will be able to more easily see and compare the various colors available as a result of this. This feature will make it easier for customers to find the color they want, which could lead to an increase in sales.
Displaying variations with different values for selected options You can specify options, and the Variable Product will only display variations with different values of those options. Using variable apps, you can display variants on the Collections page, just like you would on the featured collections. Variable shopify development apps enable you to divide products into groups and display variations on collection pages.
Step 1: From your Shopify admin, go to Online Store > Themes.
Step2: Find the theme you want to edit, and then click Actions > Edit code
Required files: section [main-collection-product-grid.liquid] , asset [component-card.css] , snippets [price.liquid],[product-card-variant.liquid] , template [collection .variant.json].
Step 3: In the Section directory, Find a file named main-collection-product-grid.liquid and find the following code:
- Step 4: And replace the code with the following:.
<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 -%}
<li class="grid__item">
{% render 'card-product',
card_product: product,
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>
{%- endfor -%}
</ul>
<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
"
>
{% if template == 'collection.variant' %}
{% for product in collection.products %}
{% assign lazy_load = false %}
{%- if forloop.index > 2 -%}
{%- assign lazy_load = true -%}
{%- endif -%}
{% assign product_option_color = false %}
{% for product_option in product.options_with_values %}
{%if product_option.name == "Color" %}
{% assign product_option_color = true %}
{% assign product_option_key = 'option' | append: forloop.index %}
{% for value in product_option.values %}
{% for variant in product.variants %}
{% if value == variant[product_option_key] %}
<li class="grid__item variant">
{% render 'product-card-variant',
product_card_product: product,
media_size: section.settings.image_ratio,
show_secondary_image: section.settings.show_secondary_image,
add_image_padding: section.settings.add_image_padding,
show_vendor: section.settings.show_vendor,
show_image_outline: section.settings.show_image_outline,
show_rating: section.settings.show_rating,
show_quick_add: section.settings.enable_quick_add,
product_option_key: product_option_key,
variant: variant
%}
</li>
{% break %}
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
{% if product_option_color == false %}
<li class="grid__item">
{% render 'card-product',
card_product: product,
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 %}
{%- endfor -%}
{% else %}
{%- for product in collection.products -%}
{% assign lazy_load = false %}
{%- if forloop.index > 2 -%}
{%- assign lazy_load = true -%}
{%- endif -%}
<li class="grid__item">
{% render 'card-product',
card_product: product,
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>
{%- endfor -%}
{% endif %}
</ul>
Step 5: In the asset directory, find a file named component-card.css and add the following code:
/********Collection page style for variant image Start***********/
.variant .card--text-only .card__inner{
grid-template-rows: auto;
}
/********Collection page style for variant image End***********/
Step 6: In the snippet directory, find a file named price.liquid and find the below code:
{%- liquid
if use_variant
assign target = product.selected_or_first_available_variant
else
assign target = product
endif
assign compare_at_price = target.compare_at_price
assign price = target.price | default: 1999
assign available = target.available | default: false
assign money_price = price | money
if settings.currency_code_enabled
assign money_price = price | money_with_currency
endif
if target == product and product.price_varies
assign money_price = 'products.product.price.from_price_html' | t: price: money_price
endif
-%}
Step 7: and replace it with the following code:
{% if variant.title %}
{%- liquid
assign target = variant
assign compare_at_price = target.compare_at_price
assign price = target.price | default: 1999
assign available = target.available | default: false
assign money_price = price | money
if settings.currency_code_enabled
assign money_price = price | money_with_currency
endif
if target == product and product.price_varies
assign money_price = 'products.product.price.from_price_html' | t: price: money_price
endif
-%}
{% else %}
{%- liquid
if use_variant
assign target = product.selected_or_first_available_variant
else
assign target = product
endif
assign compare_at_price = target.compare_at_price
assign price = target.price | default: 1999
assign available = target.available | default: false
assign money_price = price | money
if settings.currency_code_enabled
assign money_price = price | money_with_currency
endif
if target == product and product.price_varies
assign money_price = 'products.product.price.from_price_html' | t: price: money_price
endif
-%}
{% endif %}
Step 8: In the snippet directory, create a new file named product-card-variant.liquid and paste the following code into it:
{% comment %}
Renders a product 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. Default: false (optional)
- horizontal_quick_add: {Boolean} Changes the quick add button styles when set to true. Default: false (optional)
Usage:
{% render 'card-product', show_vendor: section.settings.show_vendor %}
{% endcomment %}
{{ 'component-rating.css' | asset_url | stylesheet_tag }}
{%- if variant and variant != empty -%}
{%- liquid
assign ratio = 1
if variant.featured_media and media_aspect_ratio == 'portrait'
assign ratio = 0.8
elsif variant.featured_media and media_aspect_ratio == 'adapt'
assign ratio = variant.featured_media.aspect_ratio
endif
if ratio == 0 or ratio == null
assign ratio = 1
endif
-%}
<div class="card-wrapper product-card-wrapper underline-links-hover">
<div
class="
card
card--{{ settings.card_style }}
{% if variant.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 variant.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 variant.featured_media or settings.card_style == 'standard' %} ratio{% endif %}"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
{%- if variant.featured_media -%}
<div class="card__media">
<div class="media media--transparent media--hover-effect">
{% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
<img
srcset="
{%- if variant.featured_media.width >= 165 -%}{{ variant.featured_media | image_url: width: 165 }} 165w,{%- endif -%}
{%- if variant.featured_media.width >= 360 -%}{{ variant.featured_media | image_url: width: 360 }} 360w,{%- endif -%}
{%- if variant.featured_media.width >= 533 -%}{{ variant.featured_media | image_url: width: 533 }} 533w,{%- endif -%}
{%- if variant.featured_media.width >= 720 -%}{{ variant.featured_media | image_url: width: 720 }} 720w,{%- endif -%}
{%- if variant.featured_media.width >= 940 -%}{{ variant.featured_media | image_url: width: 940 }} 940w,{%- endif -%}
{%- if variant.featured_media.width >= 1066 -%}{{ variant.featured_media | image_url: width: 1066 }} 1066w,{%- endif -%}
{{ variant.featured_media | image_url }} {{ card_product.featured_media.width }}w
"
src="{{ variant.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="{{ variant.featured_media.alt | escape }}"
class="motion-reduce"
{% unless lazy_load == false %}
loading="lazy"
{% endunless %}
width="{{ variant.featured_media.width }}"
height="{{ variant.featured_media.height }}"
>
{% comment %}theme-check-enable ImgLazyLoading{% endcomment %}
{%- if variant.media[1] != null and show_secondary_image -%}
<img
srcset="
{%- if variant.media[1].width >= 165 -%}{{ variant.media[1] | image_url: width: 165 }} 165w,{%- endif -%}
{%- if variant.media[1].width >= 360 -%}{{ variant.media[1] | image_url: width: 360 }} 360w,{%- endif -%}
{%- if variant.media[1].width >= 533 -%}{{ variant.media[1] | image_url: width: 533 }} 533w,{%- endif -%}
{%- if variant.media[1].width >= 720 -%}{{ variant.media[1] | image_url: width: 720 }} 720w,{%- endif -%}
{%- if variant.media[1].width >= 940 -%}{{ variant.media[1] | image_url: width: 940 }} 940w,{%- endif -%}
{%- if variant.media[1].width >= 1066 -%}{{ variant.media[1] | image_url: width: 1066 }} 1066w,{%- endif -%}
{{ variant.media[1] | image_url }} {{ variant.media[1].width }}w
"
src="{{ variant.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="{{ variant.media[1].width }}"
height="{{ variant.media[1].height }}"
>
{%- endif -%}
</div>
</div>
{%- endif -%}
<div class="card__content">
<div class="card__information">
<h3
class="card__heading"
{% if variant.featured_media == null and settings.card_style == 'standard' %}
id="title-{{ section_id }}-{{ variant.id }}"
{% endif %}
>
<a
href="{{ variant.url }}"
id="StandardCardNoMediaLink-{{ section_id }}-{{ variant.id }}"
class="full-unstyled-link"
aria-labelledby="StandardCardNoMediaLink-{{ section_id }}-{{ variant.id }} NoMediaStandardBadge-{{ section_id }}-{{ variant.id }}"
>
{{ product_card_product.title | escape }} - {{variant[product_option_key]}}
</a>
</h3>
</div>
<div class="card__badge {{ settings.badge_position }}">
{%- if product_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 variant.featured_media or settings.card_style == 'standard' %} h5{% endif %}"
{% if variant.featured_media or settings.card_style == 'card' %}
id="title-{{ section_id }}-{{ variant.id }}"
{% endif %}
>
<a
href="{{ variant.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 }}"
>
{{ product_card_product.title | escape }} - {{variant[product_option_key]}}
</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 product_card_product.metafields.reviews.rating.value != blank -%}
{% liquid
assign rating_decimal = 0
assign decimal = product_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: product_card_product.metafields.reviews.rating.value, rating_max: product_card_product.metafields.reviews.rating.value.scale_max }}"
>
<span
aria-hidden="true"
class="rating-star color-icon-{{ settings.accent_icons }}"
style="--rating: {{ product_card_product.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ product_card_product.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"
></span>
</div>
<p class="rating-text caption">
<span aria-hidden="true">
{{- product_card_product.metafields.reviews.rating.value }} /
{{ product_card_product.metafields.reviews.rating.value.scale_max -}}
</span>
</p>
<p class="rating-count caption">
<span aria-hidden="true">({{ product_card_product.metafields.reviews.rating_count }})</span>
<span class="visually-hidden">
{{- product_card_product.metafields.reviews.rating_count }}
{{ 'accessibility.total_reviews' | t -}}
</span>
</p>
{%- endif -%}
{% render 'price', product: variant, 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: product_card_product.id -%}
{%- if product_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="{{ variant.id }}"
>
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="quick-add__submit button button--full-width button--secondary{% if horizontal_quick_add %} card--horizontal__quick-add{% endif %}"
aria-haspopup="dialog"
aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ variant.id }}"
aria-live="polite"
data-sold-out-message="true"
{% if variant.available == false %}
disabled
{% endif %}
>
<span>
{%- if 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>
{%- if horizontal_quick_add -%}
<span class="icon-wrap">{% render 'icon-plus' %}</span>
{%- endif -%}
<div class="loading-overlay__spinner hidden">
<svg
aria-hidden="true"
focusable="false"
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-{{ variant.id }}">
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="quick-add__submit button button--full-width button--secondary{% if horizontal_quick_add %} card--horizontal__quick-add animate-arrow{% endif %}"
aria-haspopup="dialog"
aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ variant.id }}"
data-product-url="{{ variant.url }}"
>
{{ 'products.product.choose_options' | t }}
{%- if horizontal_quick_add -%}
<span class="icon-wrap">{% render 'icon-arrow' %}</span>
{%- endif -%}
<div class="loading-overlay__spinner hidden">
<svg
aria-hidden="true"
focusable="false"
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-{{ variant.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-{{ variant.id }}"
type="button"
class="quick-add-modal__toggle"
aria-label="{{ 'accessibility.close' | t }}"
>
{% render 'icon-close' %}
</button>
<div id="QuickAddInfo-{{ variant.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 variant.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 -%}
Step 9: In the template directory, create a new file named collection.variant.json and paste the following code into it:
{
"sections": {
"banner": {
"type": "main-collection-banner",
"settings": {
"show_collection_description": true,
"show_collection_image": false,
"color_scheme": "background-1"
}
},
"product-grid": {
"type": "main-collection-product-grid",
"settings": {
"products_per_page": 16,
"columns_desktop": 4,
"image_ratio": "adapt",
"show_secondary_image": false,
"show_vendor": false,
"show_rating": false,
"enable_filtering": true,
"enable_sorting": true,
"columns_mobile": "2",
"padding_top": 36,
"padding_bottom": 36
}
}
},
"order": [
"banner",
"product-grid"
]
}
Congrats, You’ve completed the coding parts.
Note: Go to the collection and assign a variant template to the collection.
Frequently Asked Questions:
How do I display color variants on Shopify’s collection page?
To do so, navigate to Customize Theme > Colors and select the desired color swatch. Then, navigate to Collection Pages > Product Grid and enable Color Swatches. A Shopify App Store app can also be used to display color swatches.
On Shopify, how do I display colors?
Navigate to Online Store > Themes from your Shopify admin. Locate the theme you want to change, then go to Actions > Edit code. Click the Snippets heading on the left side to reveal your Snippets content. Give your new snippet the name’ swatch.’
How do I customize my Shopify collections?
In the Shopify app, go to Products > Collections. Change the conditions of the collection by tapping it. Click the pencil icon to edit the collection. Change the selection conditions in the Conditions section if necessary.
On Shopify collections, how do I display product tags?
Click Products, Transfers, Customers, Blog Posts, or Draft Orders in your Shopify admin. Examine the product, transfer, customer, blog post, or draught order to which you want to apply a tag. Tags can be added or removed by clicking Add tags or Remove tags. Select the tags you want to add or remove by clicking on them.
In Shopify, how do I see variants?
A product’s variants are listed on the product details page. The Inventory page also allows you to manage inventory for each variant. If you want to save specialized information for your variants, you can use Metafields to add custom fields to your variant details pages.