Compatibility: All Shopify 2.0 FREE themes ONLY. Works from lower version to version 11
Due to the recent update in Dawn theme, Dawn version 7.0 will have far different code. See comment below.
You have only a few products but each product has multiple variants? Showcase your product in a collection but its variant. Show variants on collection pages as separate products.
We will displaying variants as products in collection pages with a secondary image on hover. The variant only allows one image currently right? We can add more image using metafield.
This will show all variants in the product. If you want to use color only, please see this code instead.
Note: If your product does not have a variant image, it will display as one product. So make sure you assign an image to your variants.
I used the following variant metafield below. NOTE: Make sure to edit the Namespace and key to match it below.

We have to add metafield to our variant. Then set up our metafield in our product variant. Please see the video for more information.
What you are buying:
- A collection of instead products, it will show ALL product variants
- The filter works in filtering the product and NOT by variants
- You will need to provide featured images to the variants
- Use metafield variant image to provide hover image
What makes our code better:
- We do not use external libraries, with that being said, our code will have no to minimal effect to your website's speed performance
- We do not leave or add codes use to advertise for our website
- Our code is mobile friendly
Any issues related to the code will be fix with no additional cost, excluding code customization requests. Simply contact us with "Chat with us." We are just a button away.
To start:
1. Go to Admin store > Online Store > Themes > Actions > Edit code.
2. Go to Section folder, and click "add a new section", name it "variant-collection."
{{ 'template-collection.css' | asset_url | stylesheet_tag }} {{ 'component-loading-overlay.css' | asset_url | stylesheet_tag }} {{ 'component-card.css' | asset_url | stylesheet_tag }} {{ 'component-price.css' | asset_url | stylesheet_tag }} <link rel="preload" href="{{ 'component-rte.css' | asset_url }}" as="style" onload="this.onload=null;this.rel='stylesheet'" > {%- if section.settings.enable_quick_add -%} <link rel="stylesheet" href="{{ 'quick-add.css' | asset_url }}" media="print" onload="this.media='all'"> <script src="{{ 'quick-add.js' | asset_url }}" defer="defer"></script> <script src="{{ 'product-form.js' | asset_url }}" defer="defer"></script> {%- endif -%} <noscript>{{ 'component-rte.css' | asset_url | stylesheet_tag }}</noscript> {%- style -%} .section-{{ section.id }}-padding { padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px; padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px; } .variant-wrapper.card-wrapper { height: fit-content; } .card__inner.ratio .card__media { width: 100% } @media screen and (min-width: 750px) { .section-{{ section.id }}-padding { padding-top: {{ section.settings.padding_top }}px; padding-bottom: {{ section.settings.padding_bottom }}px; } } {%- endstyle -%} <div class="section-{{ section.id }}-padding"> {% comment %} Sort is the first tabbable element when filter type is vertical {% endcomment %} {%- if section.settings.enable_sorting and section.settings.filter_type == 'vertical' -%} <facet-filters-form class="facets facets-vertical-sort page-width small-hide no-js-hidden"> <form class="facets-vertical-form" id="FacetSortForm"> <div class="facet-filters sorting caption"> <div class="facet-filters__field"> <h2 class="facet-filters__label caption-large text-body"> <label for="SortBy">{{ 'products.facets.sort_by_label' | t }}</label> </h2> <div class="select"> {%- assign sort_by = collection.sort_by | default: collection.default_sort_by -%} <select name="sort_by" class="facet-filters__sort select__select caption-large" id="SortBy" aria-describedby="a11y-refresh-page-message" > {%- for option in collection.sort_options -%} <option value="{{ option.value | escape }}" {% if option.value == sort_by %} selected="selected" {% endif %} > {{ option.name | escape }} </option> {%- endfor -%} </select> {% render 'icon-caret' %} </div> </div> <noscript> <button type="submit" class="facets__button-no-js button button--secondary"> {{ 'products.facets.sort_button' | t }} </button> </noscript> </div> <div class="product-count-vertical light" role="status"> <h2 class="product-count__text text-body"> <span id="ProductCountDesktop"> {%- if collection.results_count -%} {{ 'templates.search.results_with_count' | t: terms: collection.terms, count: collection.results_count }} {%- elsif collection.products_count == collection.all_products_count -%} {{ 'products.facets.product_count_simple' | t: count: collection.products_count }} {%- else -%} {{ 'products.facets.product_count' | t: product_count: collection.products_count, count: collection.all_products_count }} {%- endif -%} </span> </h2> <div class="loading-overlay__spinner"> <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> </div> </form> </facet-filters-form> {%- endif -%} <div class="{% if section.settings.filter_type == 'vertical' %} facets-vertical page-width{% endif %}"> {{ 'component-facets.css' | asset_url | stylesheet_tag }} <script src="{{ 'facets.js' | asset_url }}" defer="defer"></script> {%- if section.settings.enable_filtering or section.settings.enable_sorting -%} <aside aria-labelledby="verticalTitle" class="facets-wrapper{% unless section.settings.enable_filtering %} facets-wrapper--no-filters{% endunless %}{% if section.settings.filter_type != 'vertical' %} page-width{% endif %}" id="main-collection-filters" data-id="{{ section.id }}" > {% render 'facets', results: collection, enable_filtering: section.settings.enable_filtering, enable_sorting: section.settings.enable_sorting, filter_type: section.settings.filter_type %} </aside> {%- endif -%} <div class="product-grid-container{% if section.settings.filter_type == 'vertical' and section.settings.collapse_on_larger_devices %} product-grid-container-vertical{% endif %}" id="ProductGridContainer" > {%- paginate collection.products by section.settings.products_per_page -%} {%- if collection.products.size == 0 -%} <div class="collection collection--empty page-width" id="product-grid" data-id="{{ section.id }}"> <div class="loading-overlay gradient"></div> <div class="title-wrapper center"> <h2 class="title title--primary"> {{ 'sections.collection_template.empty' | t -}} <br> {{ 'sections.collection_template.use_fewer_filters_html' | t: link: collection.url, class: 'underlined-link link' }} </h2> </div> </div> {%- else -%} <div class="collection{% if section.settings.filter_type != 'vertical' %} page-width{% endif %}"> <div class="loading-overlay gradient"></div> <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 variantImage = true %} {%- for variant in product.variants -%} {% if variant.featured_image != blank %} {% assign variantImage = true %} {% else %} {% assign variantImage = false %} {% endif %} {%- endfor -%} {% if variantImage %} {%- for variant in product.variants -%} {% assign lazy_load = false %} {%- if forloop.index > 2 -%} {%- assign lazy_load = true -%} {%- endif -%} <li class="grid__item"> {% render 'variant-card', card_product: product, card_variant: variant, hide_variant_info: section.settings.hide_variant_info, show_secondary_image: section.settings.show_secondary_image, media_aspect_ratio: section.settings.image_ratio, 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 -%} {% else %} {% 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> {% endif %} {%- endfor -%} </ul> {%- if paginate.pages > 1 -%} {% render 'pagination', paginate: paginate, anchor: '' %} {%- endif -%} </div> {%- endif -%} {%- endpaginate -%} </div> </div> </div> {% schema %} { "name": "t:sections.main-collection-product-grid.name", "class": "section", "settings": [ { "type": "range", "id": "products_per_page", "min": 8, "max": 24, "step": 4, "default": 16, "label": "t:sections.main-collection-product-grid.settings.products_per_page.label" }, { "type": "range", "id": "columns_desktop", "min": 1, "max": 5, "step": 1, "default": 4, "label": "t:sections.main-collection-product-grid.settings.columns_desktop.label" }, { "type": "header", "content": "t:sections.main-collection-product-grid.settings.header__3.content" }, { "type": "select", "id": "image_ratio", "options": [ { "value": "adapt", "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__1.label" }, { "value": "portrait", "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__2.label" }, { "value": "square", "label": "t:sections.main-collection-product-grid.settings.image_ratio.options__3.label" } ], "default": "adapt", "label": "t:sections.main-collection-product-grid.settings.image_ratio.label" }, { "type": "checkbox", "id": "show_secondary_image", "default": false, "label": "t:sections.main-collection-product-grid.settings.show_secondary_image.label" }, { "type": "checkbox", "id": "show_vendor", "default": false, "label": "t:sections.main-collection-product-grid.settings.show_vendor.label" }, { "type": "checkbox", "id": "hide_variant_info", "label": "Hide variant title" }, { "type": "checkbox", "id": "show_rating", "default": false, "label": "t:sections.main-collection-product-grid.settings.show_rating.label", "info": "t:sections.main-collection-product-grid.settings.show_rating.info" }, { "type": "checkbox", "id": "enable_quick_add", "default": false, "label": "t:sections.main-collection-product-grid.settings.enable_quick_buy.label" }, { "type": "header", "content": "t:sections.main-collection-product-grid.settings.header__1.content" }, { "type": "checkbox", "id": "enable_filtering", "default": true, "label": "t:sections.main-collection-product-grid.settings.enable_filtering.label", "info": "t:sections.main-collection-product-grid.settings.enable_filtering.info" }, { "type": "select", "id": "filter_type", "options": [ { "value": "horizontal", "label": "t:sections.main-collection-product-grid.settings.filter_type.options__1.label" }, { "value": "vertical", "label": "t:sections.main-collection-product-grid.settings.filter_type.options__2.label" }, { "value": "drawer", "label": "t:sections.main-collection-product-grid.settings.filter_type.options__3.label" } ], "default": "horizontal", "label": "t:sections.main-collection-product-grid.settings.filter_type.label", "info": "t:sections.main-collection-product-grid.settings.filter_type.info" }, { "type": "checkbox", "id": "enable_sorting", "default": true, "label": "t:sections.main-collection-product-grid.settings.enable_sorting.label" }, { "type": "header", "content": "t:sections.main-collection-product-grid.settings.header_mobile.content" }, { "type": "select", "id": "columns_mobile", "default": "2", "label": "t:sections.main-collection-product-grid.settings.columns_mobile.label", "options": [ { "value": "1", "label": "t:sections.main-collection-product-grid.settings.columns_mobile.options__1.label" }, { "value": "2", "label": "t:sections.main-collection-product-grid.settings.columns_mobile.options__2.label" } ] }, { "type": "header", "content": "t:sections.all.padding.section_padding_heading" }, { "type": "range", "id": "padding_top", "min": 0, "max": 100, "step": 4, "unit": "px", "label": "t:sections.all.padding.padding_top", "default": 36 }, { "type": "range", "id": "padding_bottom", "min": 0, "max": 100, "step": 4, "unit": "px", "label": "t:sections.all.padding.padding_bottom", "default": 36 } ] } {% endschema %} |
3. If you want to assign this collection template as a default, then follow the video.
If not, we need to create a new collection template. (Follow the video on how). Open and copy the code in the "collection.json" under the Template folder. Then paste the code to the newly created template.
Inside the newly created template, find this code "main-collection-product-grid" and replace with the name "variant-collection".
4. Next, we need to create a variant card. Open the Snippet folder, and click "Add a new snippet." Name it "variant-card." If you have Dawn version 6.0 below use the code below, if not, please use the next code.
For Dawn 6.0 below
{% 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. Usage: {% render 'variant-card', show_vendor: section.settings.show_vendor %} {% endcomment %} {{ 'component-rating.css' | asset_url | stylesheet_tag }} {%- 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="variant-wrapper 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 extend_height %} card--extend-height{% endif %} {% if card_variant.featured_media == nil and settings.card_style == 'card' %} ratio{% 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_variant.featured_media -%} <div class="card__media"> <div class="media media--transparent media--hover-effect"> {% comment %}theme-check-disable ImgLazyLoading{% endcomment %} <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 }}" > {% comment %}theme-check-enable ImgLazyLoading{% endcomment %} {% assign meta_image = card_variant.metafields.my_fields['secondary-image'] %} {% if meta_image != null and show_secondary_image %} <img src="{{ meta_image | 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="{{ meta_image.alt | escape }}" class="motion-reduce" loading="lazy" width="{{ meta_image.width }}" height="{{ meta_image.height }}" > {% endif %} </div> </div> {%- endif -%} </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_product.id }}" {% endif %} > <a href="{{ card_variant.url }}" class="full-unstyled-link"> {{ card_product.title | escape }} <br> {{ card_variant.title | escape }} </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_variant, price_class: '' %} </div> </div> {%- if show_quick_add -%} <div class="quick-add"> {%- assign product_form_id = 'quick-add-' | append: section_id | append: card_variant.id -%} {%- if card_product.has_only_default_variant -%} <product-form> {%- form 'product', card_variant, id: product_form_id, class: 'form', novalidate: 'novalidate', data-type: 'add-to-cart-form' -%} <input type="hidden" name="id" value="{{ card_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_variant.id }}" aria-live="polite" data-sold-out-message="true" {% if card_variant.available == false %} disabled {% endif %} > <span> {%- if card_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_variant.available == false -%} <span 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 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 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_variant.featured_media == nil and settings.card_style == 'card' %} ratio{% endif %} " 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 -%} |
For Dawn 7.0 and higher
{% 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) - image_shape: {String} Image mask to apply to the product image card. Values are "arch", "blob", "chevronleft", "chevronright", "diamond", "parallelogram", and "round". (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) - placeholder_image: {String} The placeholder image to use when no product exists. Default: 'product-apparel-2' (optional) Usage: {% render 'card-product', 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_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"> {% comment %}theme-check-disable ImgLazyLoading{% endcomment %} <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 }}" > {% comment %}theme-check-enable ImgLazyLoading{% endcomment %} {%- if card_variant.metafields.my_fields.secondary_image != null and show_secondary_image -%} <img srcset=" {%- if card_variant.metafields.my_fields.secondary_image.width >= 165 -%}{{ card_variant.metafields.my_fields.secondary_image | image_url: width: 165 }} 165w,{%- endif -%} {%- if card_variant.metafields.my_fields.secondary_image.width >= 360 -%}{{ card_variant.metafields.my_fields.secondary_image | image_url: width: 360 }} 360w,{%- endif -%} {%- if card_variant.metafields.my_fields.secondary_image.width >= 533 -%}{{ card_variant.metafields.my_fields.secondary_image | image_url: width: 533 }} 533w,{%- endif -%} {%- if card_variant.metafields.my_fields.secondary_image.width >= 720 -%}{{ card_variant.metafields.my_fields.secondary_image | image_url: width: 720 }} 720w,{%- endif -%} {%- if card_variant.metafields.my_fields.secondary_image.width >= 940 -%}{{ card_variant.metafields.my_fields.secondary_image | image_url: width: 940 }} 940w,{%- endif -%} {%- if card_variant.metafields.my_fields.secondary_image.width >= 1066 -%}{{ card_variant.metafields.my_fields.secondary_image | image_url: width: 1066 }} 1066w,{%- endif -%} {{ card_variant.metafields.my_fields.secondary_image | image_url }} {{ card_variant.metafields.my_fields.secondary_image.width }}w " src="{{ card_variant.metafields.my_fields.secondary_image | 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_variant.metafields.my_fields.secondary_image.width }}" height="{{ card_variant.metafields.my_fields.secondary_image.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_product.title | escape }} {% if hide_variant_info == false %} <br> {{ card_variant.title | capitalize }} {% endif %} </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_product.title | escape }} {% if hide_variant_info == false %} <br> {{ card_variant.title | capitalize }} {% endif %} </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 %} <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_product, price_class: '' %} </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_variant.id assign qty_rules = false if card_variant.quantity_rule.min > 1 or card_variant.quantity_rule.max != null or card_variant.quantity_rule.increment > 1 assign qty_rules = true endif -%} {%- if card_variant.variants.size > 1 or qty_rules -%} <modal-opener data-modal="#QuickAdd-{{ card_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 }}-{{ card_variant.id }}" data-product-url="{{ card_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-{{ card_variant.id }}" class="quick-add-modal"> <div role="dialog" aria-label="{{ 'products.product.choose_product_options' | t: product_name: card_variant.title | escape }}" aria-modal="true" class="quick-add-modal__content global-settings-popup" tabindex="-1" > <button id="ModalClose-{{ card_variant.id }}" type="button" class="quick-add-modal__toggle" aria-label="{{ 'accessibility.close' | t }}" > {% render 'icon-close' %} </button> <div id="QuickAddInfo-{{ card_variant.id }}" class="quick-add-modal__content-info"></div> </div> </quick-add-modal> {%- else -%} <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_variant.id }}" disabled > <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_variant.id }}" aria-live="polite" data-sold-out-message="true" {% if card_variant.available == false %} disabled {% endif %} > <span> {%- if card_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> {%- endif -%} </div> {%- endif -%} <div class="card__badge {{ settings.badge_position }}"> {%- if card_variant.available == false -%} <span id="Badge-{{ 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="Badge-{{ 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> {%- else -%} <div class="card-wrapper product-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_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__media"> {%- if placeholder_image -%} {{ placeholder_image | placeholder_svg_tag: 'placeholder-svg' }} {%- else -%} {{ 'product-apparel-2' | placeholder_svg_tag: 'placeholder-svg' }} {%- endif -%} </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' %} </div> </div> </div> </div> </div> {%- endif -%} |
5. Make sure to SAVE
That is it (",)
4 comments
@DHEL DOMINCIL,
At this moment, the filter does not work with this. I have not get a chance to write a specific filter for this but stay tuned.
Cool tutorial! I do have a question:
With the variants showing as individual products on the collection, will the filter(s) for a collection page filter out the specific variants as well?
As an example: If there are several different products that all have a green variant, and customer wants to see only green products, will the filter on the collection page show only those green variants fafter filter?
Hi @Binaebi,
This should work in any Shopify 2.0 FREE themes, since they share the same code, the only difference is the CSS which is not much. Can you message me in “Chat with us” to discuss what gone wrong? Thank you
This did not work with the Studio theme. It broke the collection and won’t show the filters or even the default products. Everything after the collection banner is gone.