For Horizon Theme Version 3+
Github Repo for Developers to contribute to the code: https://github.com/bilalnaseer/shopify-sections/blob/main/show_variants_as_separate_products/section.liquid
This code should work completely fine with all of the latest Horizon Themes and Paid themes as well
{% assign wsp_section_id = section.id | replace: '_', '' | downcase %}
{% style %}
.variant-products-{{ wsp_section_id }} {
padding: {{ section.settings.section_padding_top }}px 0 {{ section.settings.section_padding_bottom }}px;
}
.variant-products-container-{{ wsp_section_id }} {
max-width: 1400px;
margin: 0 auto;
padding: 0 20px;
}
.variant-products-header-{{ wsp_section_id }} {
text-align: {{ section.settings.heading_alignment }};
margin-bottom: 40px;
}
.variant-products-title-{{ wsp_section_id }} {
margin: 0 0 12px;
color: {{ section.settings.heading_color }};
font-size: {{ section.settings.heading_size }}px;
}
.variant-products-description-{{ wsp_section_id }} {
margin: 0;
color: {{ section.settings.text_color }};
font-size: {{ section.settings.description_size }}px;
}
.variant-products-grid-{{ wsp_section_id }} {
display: grid;
grid-template-columns: repeat({{ section.settings.columns_desktop }}, 1fr);
gap: {{ section.settings.grid_gap }}px;
}
.variant-card-{{ wsp_section_id }} {
background: {{ section.settings.card_background }};
border: {{ section.settings.card_border_width }}px solid {{ section.settings.card_border_color }};
border-radius: {{ section.settings.card_border_radius }}px;
padding: {{ section.settings.card_padding }}px;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.variant-card-{{ wsp_section_id }}:hover {
transform: translateY(-4px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
.variant-image-wrapper-{{ wsp_section_id }} {
position: relative;
width: 100%;
margin-bottom: 16px;
overflow: hidden;
border-radius: {{ section.settings.image_border_radius }}px;
}
.variant-image-{{ wsp_section_id }} {
width: 100%;
height: auto;
display: block;
aspect-ratio: {{ section.settings.image_ratio }};
object-fit: cover;
}
.variant-image-placeholder-{{ wsp_section_id }} {
width: 100%;
aspect-ratio: {{ section.settings.image_ratio }};
background-color: #f4f4f4;
display: flex;
align-items: center;
justify-content: center;
}
.variant-image-placeholder-{{ wsp_section_id }} svg {
width: 60%;
height: 60%;
opacity: 0.3;
}
.variant-badge-{{ wsp_section_id }} {
position: absolute;
top: 12px;
left: 12px;
background: {{ section.settings.badge_background }};
color: {{ section.settings.badge_text_color }};
padding: 6px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
}
.variant-info-{{ wsp_section_id }} {
margin-bottom: 16px;
}
.variant-title-{{ wsp_section_id }} {
margin: 0 0 8px;
font-size: {{ section.settings.variant_title_size }}px;
color: {{ section.settings.variant_title_color }};
font-weight: 600;
}
.variant-option-{{ wsp_section_id }} {
margin: 0 0 12px;
font-size: {{ section.settings.variant_option_size }}px;
color: {{ section.settings.variant_option_color }};
}
.variant-price-{{ wsp_section_id }} {
margin: 0 0 16px;
font-size: {{ section.settings.price_size }}px;
color: {{ section.settings.price_color }};
font-weight: 600;
}
.variant-price-compare-{{ wsp_section_id }} {
text-decoration: line-through;
opacity: 0.6;
margin-left: 8px;
font-size: {{ section.settings.price_size | times: 0.9 }}px;
}
.variant-button-{{ wsp_section_id }} {
display: inline-block;
width: 100%;
padding: 12px 24px;
background: {{ section.settings.button_background }};
color: {{ section.settings.button_text_color }};
border: {{ section.settings.button_border_width }}px solid {{ section.settings.button_border_color }};
border-radius: {{ section.settings.button_border_radius }}px;
text-decoration: none;
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
transition: all 0.3s ease;
cursor: pointer;
}
.variant-button-{{ wsp_section_id }}:hover {
background: {{ section.settings.button_hover_background }};
color: {{ section.settings.button_hover_text_color }};
border-color: {{ section.settings.button_hover_border_color }};
}
.variant-button-{{ wsp_section_id }}:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.empty-state-{{ wsp_section_id }} {
text-align: center;
padding: 60px 20px;
color: #666;
}
.empty-state-{{ wsp_section_id }} svg {
max-width: 300px;
margin: 0 auto 20px;
opacity: 0.3;
}
@media screen and (max-width: 989px) {
.variant-products-grid-{{ wsp_section_id }} {
grid-template-columns: repeat({{ section.settings.columns_tablet }}, 1fr);
}
}
@media screen and (max-width: 749px) {
.variant-products-grid-{{ wsp_section_id }} {
grid-template-columns: repeat({{ section.settings.columns_mobile }}, 1fr);
}
.variant-products-title-{{ wsp_section_id }} {
font-size: {{ section.settings.heading_size | times: 0.7 }}px;
}
.variant-card-{{ wsp_section_id }} {
padding: {{ section.settings.card_padding | times: 0.75 }}px;
}
}
{% endstyle %}
{% comment %}
LOGIC: Determine the collection source.
1. Use section setting if provided.
2. Fallback to global collection object (if on collection page).
{% endcomment %}
{% assign target_collection = section.settings.collection %}
{% if target_collection == blank and collection != blank %}
{% assign target_collection = collection %}
{% endif %}
<div class="variant-products-{{ wsp_section_id }}" {{ section.shopify_attributes }}>
<div class="variant-products-container-{{ wsp_section_id }}">
{% if section.settings.heading != blank or section.settings.description != blank %}
<div class="variant-products-header-{{ wsp_section_id }}">
{% if section.settings.heading != blank %}
<h2 class="variant-products-title-{{ wsp_section_id }}">{{ section.settings.heading }}</h2>
{% endif %}
{% if section.settings.description != blank %}
<div class="variant-products-description-{{ wsp_section_id }}">{{ section.settings.description }}</div>
{% endif %}
</div>
{% endif %}
{% if target_collection != blank %}
{% assign products_to_show = target_collection.products %}
{% if section.settings.product_limit > 0 %}
{% assign product_limit = section.settings.product_limit %}
{% else %}
{% assign product_limit = products_to_show.size %}
{% endif %}
{% assign variant_count = 0 %}
{% assign has_variants = false %}
{% if products_to_show.size > 0 %}
<div class="variant-products-grid-{{ wsp_section_id }}">
{% for product in products_to_show limit: product_limit %}
{% for variant in product.variants %}
{% if section.settings.show_unavailable or variant.available %}
{% assign variant_count = variant_count | plus: 1 %}
{% assign has_variants = true %}
<div class="variant-card-{{ wsp_section_id }}">
<div class="variant-card-top-{{ wsp_section_id }}">
<div class="variant-image-wrapper-{{ wsp_section_id }}">
{% if variant.image %}
<img
src="{{ variant.image | image_url: width: 600 }}"
alt="{{ variant.title | escape }}"
loading="lazy"
width="600"
height="600"
class="variant-image-{{ wsp_section_id }}"
>
{% elsif product.featured_image %}
<img
src="{{ product.featured_image | image_url: width: 600 }}"
alt="{{ product.title | escape }}"
loading="lazy"
width="600"
height="600"
class="variant-image-{{ wsp_section_id }}"
>
{% else %}
<div class="variant-image-placeholder-{{ wsp_section_id }}">
{{ 'product-1' | placeholder_svg_tag }}
</div>
{% endif %}
{% if section.settings.show_badges %}
{% if variant.available == false %}
<div class="variant-badge-{{ wsp_section_id }}">Sold Out</div>
{% elsif variant.compare_at_price > variant.price %}
<div class="variant-badge-{{ wsp_section_id }}">Sale</div>
{% endif %}
{% endif %}
</div>
<div class="variant-info-{{ wsp_section_id }}">
{% if section.settings.show_product_title %}
<h3 class="variant-title-{{ wsp_section_id }}">{{ product.title }}</h3>
{% endif %}
<p class="variant-option-{{ wsp_section_id }}">{{ variant.title }}</p>
<div class="variant-price-{{ wsp_section_id }}">
{{ variant.price | money }}
{% if variant.compare_at_price > variant.price %}
<span class="variant-price-compare-{{ wsp_section_id }}">{{ variant.compare_at_price | money }}</span>
{% endif %}
</div>
</div>
</div>
<div class="variant-card-bottom-{{ wsp_section_id }}">
{% if variant.available %}
<a
href="{{ variant.url }}"
class="variant-button-{{ wsp_section_id }}"
>
{{ section.settings.button_text }}
</a>
{% else %}
<button
class="variant-button-{{ wsp_section_id }}"
disabled
>
Unavailable
</button>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
</div>
{% if has_variants == false %}
<div class="empty-state-{{ wsp_section_id }}">
{{ 'collection-1' | placeholder_svg_tag }}
<p>No available variants found in this collection.</p>
</div>
{% endif %}
{% else %}
<div class="empty-state-{{ wsp_section_id }}">
{{ 'collection-1' | placeholder_svg_tag }}
<p>This collection is empty. Add products to see them here.</p>
</div>
{% endif %}
{% else %}
<div class="empty-state-{{ wsp_section_id }}">
{{ 'collection-1' | placeholder_svg_tag }}
<p>Please select a collection in the section settings, or visit a collection page to see variants.</p>
</div>
{% endif %}
</div>
</div>
{% schema %}
{
"name": "Collection variants grid",
"settings": [
{
"type": "header",
"content": "Data Source"
},
{
"type": "collection",
"id": "collection",
"label": "Collection",
"info": "Select a collection to display. Leave empty to use the current page's collection."
},
{
"type": "header",
"content": "Products"
},
{
"type": "range",
"id": "product_limit",
"min": 0,
"max": 50,
"step": 1,
"label": "Product limit",
"default": 12,
"info": "Set to 0 to show all products. Note: Each product's variants will be shown separately, so the total card count may be much higher than this number."
},
{
"type": "checkbox",
"id": "show_unavailable",
"label": "Show unavailable variants",
"default": false
},
{
"type": "header",
"content": "Content"
},
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "All Variants"
},
{
"type": "textarea",
"id": "description",
"label": "Description",
"default": "Browse all available variants from our collection"
},
{
"type": "select",
"id": "heading_alignment",
"label": "Heading alignment",
"options": [
{
"value": "left",
"label": "Left"
},
{
"value": "center",
"label": "Center"
},
{
"value": "right",
"label": "Right"
}
],
"default": "center"
},
{
"type": "checkbox",
"id": "show_product_title",
"label": "Show product title",
"default": true
},
{
"type": "checkbox",
"id": "show_badges",
"label": "Show badges",
"default": true
},
{
"type": "text",
"id": "button_text",
"label": "Button text",
"default": "View Product"
},
{
"type": "header",
"content": "Layout"
},
{
"type": "range",
"id": "columns_desktop",
"min": 2,
"max": 5,
"step": 1,
"label": "Columns on desktop",
"default": 4
},
{
"type": "range",
"id": "columns_tablet",
"min": 2,
"max": 4,
"step": 1,
"label": "Columns on tablet",
"default": 3
},
{
"type": "select",
"id": "columns_mobile",
"label": "Columns on mobile",
"options": [
{
"value": "1",
"label": "1"
},
{
"value": "2",
"label": "2"
}
],
"default": "2"
},
{
"type": "range",
"id": "grid_gap",
"min": 10,
"max": 50,
"step": 5,
"unit": "px",
"label": "Grid gap",
"default": 20
},
{
"type": "select",
"id": "image_ratio",
"label": "Image ratio",
"options": [
{
"value": "1/1",
"label": "Square"
},
{
"value": "3/4",
"label": "Portrait"
},
{
"value": "4/3",
"label": "Landscape"
}
],
"default": "1/1"
},
{
"type": "header",
"content": "Colors"
},
{
"type": "color",
"id": "heading_color",
"label": "Heading",
"default": "#a42325"
},
{
"type": "color",
"id": "text_color",
"label": "Description",
"default": "#000000"
},
{
"type": "color",
"id": "card_background",
"label": "Card background",
"default": "#ffffff"
},
{
"type": "color",
"id": "card_border_color",
"label": "Card border",
"default": "#e6e6e6"
},
{
"type": "color",
"id": "variant_title_color",
"label": "Product title",
"default": "#000000"
},
{
"type": "color",
"id": "variant_option_color",
"label": "Variant option",
"default": "#666666"
},
{
"type": "color",
"id": "price_color",
"label": "Price",
"default": "#a42325"
},
{
"type": "color",
"id": "badge_background",
"label": "Badge background",
"default": "#a42325"
},
{
"type": "color",
"id": "badge_text_color",
"label": "Badge text",
"default": "#ffffff"
},
{
"type": "header",
"content": "Button style"
},
{
"type": "color",
"id": "button_background",
"label": "Background",
"default": "#a42325"
},
{
"type": "color",
"id": "button_text_color",
"label": "Text",
"default": "#ffffff"
},
{
"type": "color",
"id": "button_border_color",
"label": "Border",
"default": "#a42325"
},
{
"type": "color",
"id": "button_hover_background",
"label": "Hover background",
"default": "#780406"
},
{
"type": "color",
"id": "button_hover_text_color",
"label": "Hover text",
"default": "#ffffff"
},
{
"type": "color",
"id": "button_hover_border_color",
"label": "Hover border",
"default": "#780406"
},
{
"type": "range",
"id": "button_border_width",
"min": 0,
"max": 4,
"step": 1,
"unit": "px",
"label": "Border width",
"default": 0
},
{
"type": "range",
"id": "button_border_radius",
"min": 0,
"max": 50,
"step": 2,
"unit": "px",
"label": "Border radius",
"default": 0
},
{
"type": "header",
"content": "Typography"
},
{
"type": "range",
"id": "heading_size",
"min": 20,
"max": 60,
"step": 2,
"unit": "px",
"label": "Heading size",
"default": 32
},
{
"type": "range",
"id": "description_size",
"min": 12,
"max": 24,
"step": 1,
"unit": "px",
"label": "Description size",
"default": 16
},
{
"type": "range",
"id": "variant_title_size",
"min": 12,
"max": 24,
"step": 1,
"unit": "px",
"label": "Product title size",
"default": 16
},
{
"type": "range",
"id": "variant_option_size",
"min": 12,
"max": 20,
"step": 1,
"unit": "px",
"label": "Variant option size",
"default": 14
},
{
"type": "range",
"id": "price_size",
"min": 14,
"max": 28,
"step": 1,
"unit": "px",
"label": "Price size",
"default": 18
},
{
"type": "header",
"content": "Spacing"
},
{
"type": "range",
"id": "section_padding_top",
"min": 0,
"max": 100,
"step": 5,
"unit": "px",
"label": "Top padding",
"default": 50
},
{
"type": "range",
"id": "section_padding_bottom",
"min": 0,
"max": 100,
"step": 5,
"unit": "px",
"label": "Bottom padding",
"default": 50
},
{
"type": "range",
"id": "card_padding",
"min": 10,
"max": 40,
"step": 2,
"unit": "px",
"label": "Card padding",
"default": 20
},
{
"type": "range",
"id": "card_border_width",
"min": 0,
"max": 4,
"step": 1,
"unit": "px",
"label": "Card border width",
"default": 1
},
{
"type": "range",
"id": "card_border_radius",
"min": 0,
"max": 20,
"step": 2,
"unit": "px",
"label": "Card border radius",
"default": 0
},
{
"type": "range",
"id": "image_border_radius",
"min": 0,
"max": 20,
"step": 2,
"unit": "px",
"label": "Image border radius",
"default": 0
}
],
"presets": [
{
"name": "Show Variant As Separate Products"
}
]
}
{% endschema %}
For Dawn Theme Version 12 and Below:
Introduction
Welcome back to the channel! In today’s video, we have an exciting Shopify tutorial for you, focusing on enhancing your collection page by displaying product variants as separate products.. The best part? No need to install any apps or purchase subscriptions – just follow this step-by-step guide.
Installing the Dawn 12.0.0 Theme
For this demonstration, we’ll install a fresh Dawn 12.0.0 theme. As of December 3rd, 2023, this tutorial is compatible with the latest version. Click the “Add” button to install the theme, then publish it.
Setting Up Variant Images
Before diving into code changes, ensure that each variant has an associated image. This is crucial for a seamless implementation. Edit your product, select the appropriate image for each variant, and save the changes.
Code Implementation
To achieve the desired display, we’ll follow a two-step code implementation process.
Adding a New Snippet
Access the backend, add a new snippet named ‘card-variant.liquid,’ and paste the provided code. Save the changes.
Updating the Collection Product Grid
Navigate to the ‘main-collection-product-grid.liquid’ file, locate the existing code for product display, and replace it with the provided code
from the tutorial. Save the changes.
Create a new snippet called card-variant.liquid with the following code:
{{ 'component-rating.css' | asset_url | stylesheet_tag }}
{{ 'component-volume-pricing.css' | asset_url | stylesheet_tag }}
{% comment %}
Code is tested by WebSensePro team with Dawn 12.0.0 Theme
Code is subject to be updated with every theme updates, for more info contact via https://websensepro.com/contact-us
{% endcomment %}
{%- if card_variant and card_variant != empty -%}
{%- liquid
assign ratio = 1
if card_variant.featured_media and media_aspect_ratio == 'portrait'
assign ratio = 0.8
elsif card_variant.featured_media and media_aspect_ratio == 'adapt'
assign ratio = card_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 card_variant.featured_media %} card--media{% else %} card--text{% endif %}
{% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
{% if image_shape and image_shape != 'default' %} card--shape{% endif %}
{% if extend_height %} card--extend-height{% endif %}
{% if card_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 card_variant.featured_media or settings.card_style == 'standard' %} ratio{% endif %}"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
{%- if card_variant.featured_media -%}
<div class="card__media{% if image_shape and image_shape != 'default' %} shape--{{ image_shape }} color-{{ settings.card_color_scheme }} gradient{% endif %}">
<div class="media media--transparent media--hover-effect">
<img
srcset="
{%- if card_variant.featured_media.width >= 165 -%}{{ card_variant.featured_media | image_url: width: 165 }} 165w,{%- endif -%}
{%- if card_variant.featured_media.width >= 360 -%}{{ card_variant.featured_media | image_url: width: 360 }} 360w,{%- endif -%}
{%- if card_variant.featured_media.width >= 533 -%}{{ card_variant.featured_media | image_url: width: 533 }} 533w,{%- endif -%}
{%- if card_variant.featured_media.width >= 720 -%}{{ card_variant.featured_media | image_url: width: 720 }} 720w,{%- endif -%}
{%- if card_variant.featured_media.width >= 940 -%}{{ card_variant.featured_media | image_url: width: 940 }} 940w,{%- endif -%}
{%- if card_variant.featured_media.width >= 1066 -%}{{ card_variant.featured_media | image_url: width: 1066 }} 1066w,{%- endif -%}
{{ card_variant.featured_media | image_url }} {{ card_variant.featured_media.width }}w
"
src="{{ card_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="{{ card_variant.featured_media.alt | escape }}"
class="motion-reduce"
{% unless lazy_load == false %}
loading="lazy"
{% endunless %}
width="{{ card_variant.featured_media.width }}"
height="{{ card_variant.featured_media.height }}"
>
{%- if card_product.media[1] != null 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_variant.featured_media == null and settings.card_style == 'standard' %}
id="title-{{ section_id }}-{{ card_variant.id }}"
{% endif %}
>
<a
href="{{ card_variant.url }}"
id="StandardCardNoMediaLink-{{ section_id }}-{{ card_variant.id }}"
class="full-unstyled-link"
aria-labelledby="StandardCardNoMediaLink-{{ section_id }}-{{ card_variant.id }} NoMediaStandardBadge-{{ section_id }}-{{ card_variant.id }}"
>
{{ card_variant.product.title | escape }} - {{ variant_option }}
</a>
</h3>
</div>
<div class="card__badge {{ settings.badge_position }}">
{%- if card_variant.available == false -%}
<span
id="NoMediaStandardBadge-{{ section_id }}-{{ card_variant.id }}"
class="badge badge--bottom-left color-{{ settings.sold_out_badge_color_scheme }}"
>
{{- 'products.product.sold_out' | t -}}
</span>
{%- elsif card_variant.compare_at_price > card_variant.price and card_variant.available -%}
<span
id="NoMediaStandardBadge-{{ section_id }}-{{ card_variant.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_variant.featured_media or settings.card_style == 'standard' %} h5{% endif %}"
{% if card_variant.featured_media or settings.card_style == 'card' %}
id="title-{{ section_id }}-{{ card_variant.id }}"
{% endif %}
>
<a
href="{{ card_variant.url }}"
id="CardLink-{{ section_id }}-{{ card_variant.id }}"
class="full-unstyled-link"
aria-labelledby="CardLink-{{ section_id }}-{{ card_variant.id }} Badge-{{ section_id }}-{{ card_variant.id }}"
>
{{ card_variant.product.title | escape }} - {{ variant_option }}
</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_variant.vendor }}</div>
{%- endif -%}
<span class="caption-large light">{{ block.settings.description | escape }}</span>
{%- if show_rating and card_variant.metafields.reviews.rating.value != blank -%}
{% liquid
assign rating_decimal = 0
assign decimal = card_variant.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
%}
{% comment %}
Code is tested by WebSensePro team with Dawn 12.0.0 Theme
Code is subject to be updated with every theme updates, for more info contact via https://websensepro.com/contact-us
{% endcomment %}
<div
class="rating"
role="img"
aria-label="{{ 'accessibility.star_reviews_info' | t: rating_value: card_variant.metafields.reviews.rating.value, rating_max: card_variant.metafields.reviews.rating.value.scale_max }}"
>
<span
aria-hidden="true"
class="rating-star"
style="--rating: {{ card_variant.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ card_variant.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"
></span>
</div>
<p class="rating-text caption">
<span aria-hidden="true">
{{- card_variant.metafields.reviews.rating.value }} /
{{ card_variant.metafields.reviews.rating.value.scale_max -}}
</span>
</p>
<p class="rating-count caption">
<span aria-hidden="true">({{ card_variant.metafields.reviews.rating_count }})</span>
<span class="visually-hidden">
{{- card_variant.metafields.reviews.rating_count }}
{{ 'accessibility.total_reviews' | t -}}
</span>
</p>
{%- endif -%}
{% render 'price', product: card_variant, price_class: '', show_compare_at_price: true %}
{%- if card_variant.quantity_price_breaks_configured? -%}
<div class="card__information-volume-pricing-note">
<span class="caption">{{ 'products.product.volume_pricing.note' | t }}</span>
</div>
{%- endif -%}
</div>
</div>
{%- if show_quick_add -%}
<div class="quick-add no-js-hidden">
{%- liquid
assign product_form_id = 'quick-add-' | append: section_id | append: card_product.id
assign qty_rules = false
if card_product.selected_or_first_available_variant.quantity_rule.min > 1 or card_product.selected_or_first_available_variant.quantity_rule.max != null or card_product.selected_or_first_available_variant.quantity_rule.increment > 1
assign qty_rules = true
endif
-%}
{%- if card_product.variants.size > 1 or qty_rules -%}
<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{% if horizontal_quick_add %} card--horizontal__quick-add animate-arrow{% endif %}"
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 }}
{%- if horizontal_quick_add -%}
<span class="icon-wrap">{% render 'icon-arrow' %}</span>
{%- endif -%}
{%- render 'loading-spinner' -%}
</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>
{%- else -%}
<product-form data-section-id="{{ section.id }}">
{%- 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 }}"
class="product-variant-id"
{% if card_product.selected_or_first_available_variant.available == false %}
disabled
{% endif %}
>
<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 }}-{{ 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>
{%- if horizontal_quick_add -%}
<span class="icon-wrap">{% render 'icon-plus' %}</span>
{%- endif -%}
{%- render 'loading-spinner' -%}
</button>
{%- endform -%}
</product-form>
{%- 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="card-wrapper product-card-wrapper underline-links-hover">
<div
class="
card card--{{ settings.card_style }}
{% if extend_height %} card--extend-height{% endif %}
{% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
"
style="--ratio-percent: 100%;"
>
<div
class="card__inner{% if settings.card_style == 'standard' %} color-{{ settings.card_color_scheme }} gradient{% endif %} ratio"
style="--ratio-percent: 100%;"
>
<div class="card__media">
<div class="media media--transparent">
{%- if placeholder_image -%}
{{ placeholder_image | placeholder_svg_tag: 'placeholder-svg' }}
{%- else -%}
{{ 'product-apparel-2' | placeholder_svg_tag: 'placeholder-svg' }}
{% endif %}
</div>
</div>
</div>
<div class="card__content">
<div class="card__information">
<h3 class="card__heading card__heading--placeholder{% 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', show_compare_at_price: true %}
</div>
</div>
</div>
</div>
</div>
{%- endif -%}
Replace the following code in main-collection-product-grid.liquid:
<li
class="grid__item{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
{% if settings.animations_reveal_on_scroll %}
data-cascade
style="--animation-order: {{ forloop.index }};"
{% endif %}
>
{% render 'card-product',
card_product: product,
media_aspect_ratio: section.settings.image_ratio,
image_shape: section.settings.image_shape,
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>
With following code:
{%- liquid
assign option_chosen = "Color"
assign option_index = ''
for option in product.options
if option_chosen == option
assign option_index = forloop.index0
break
endif
endfor
-%}
{% comment %}
Code is tested by WebSensePro team with Dawn 12.0.0 Theme
Code is subject to be updated with every theme updates, for more info contact via https://websensepro.com/contact-us
{% endcomment %}
{%- if option_index == '' -%}
<li
class="grid__item{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
{% if settings.animations_reveal_on_scroll %}
data-cascade
style="--animation-order: {{ forloop.index }};"
{% endif %}
>
{% render 'card-product',
card_product: product,
media_aspect_ratio: section.settings.image_ratio,
image_shape: section.settings.image_shape,
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>
{%- else -%}
{% assign displayed_values = "" %}
{% for variant in product.variants %}
{%- liquid
assign variant_option = variant.options[option_index]
assign valueIsDisplayed = false
for value in displayed_values
if value == variant_option
assign valueIsDisplayed = true
break
endif
endfor
-%}
{% unless valueIsDisplayed %}
{%- assign variant_option_arr = variant_option | append: ';' | split: ';' -%}
{% assign displayed_values = displayed_values | concat: variant_option_arr %}
<li
class="grid__item{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
{% if settings.animations_reveal_on_scroll %}
data-cascade
style="--animation-order: {{ forloop.index }};"
{% endif %}
>
{% render 'card-variant',
card_variant: variant,
card_product: product,
variant_option: variant_option,
media_aspect_ratio: section.settings.image_ratio,
image_shape: section.settings.image_shape,
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>
{% endunless %}
{% endfor %}
{%- endif -%}
Preview and Customize
After implementing the code changes, preview your theme and head to the collection page. You’ll now notice that each variant is displayed as a separate product, enriching the overall user experience.
Bonus Tip: Displaying Variants by Size
Customization doesn’t stop there! As shown in the tutorial, you can easily modify the code to display variants based on size rather than color. Simply update the specified option to ‘size’ in the code.