Product Swatch

Variant Image Swatch - Dawn

How to see the code

1. Please log in/create an account first. This is to ensure that all purchases are connected to an account and can be viewed on different devices.

2. Purchase the code using the "purchase box" on the specific page of the desired code.

3. After the purchase, please refresh the page.

Compatibility: Compatible with any version of Dawn and any Shopify 2..0 FREE themes.

Use the variant image as the image swatch for your product. You can either drop down or radio buttons for the variant picker. You can also add this swatches to your product card so first 4 variant images will show in  the collection page. 

1. Go to Online Store > Themes > Actions > Edit Code.

2. Open the main-product.liquid file under the Section folder and find the code below.

{%- when 'variant_picker' -%} 

 

3. We need to replace the code between the code in Step 2 and the code below, with the code in Step 4.

{%- when 'buy_buttons' -%}

 

4. If you have a name "Color" other than "Color", you have to change the option_name. Note: It is case sensitive. You can also change the size of the swatch by change the swatchSize variable.

{% assign option_name = "Color,Style,Colour" %}

{% assign swatch_size = '3vw' %} {% comment %} Change the color swatch size below.{% endcomment %}
{% assign swatch_shape = 'round-edge' %} {% comment %} Change the swatch shape. Use either 'round', 'square', 'rectangle' or 'round-edge'. {% endcomment %}

{%- unless product.has_only_default_variant -%}
{% assign picker_type = block.settings.picker_type %}
{%- if picker_type == 'button' -%}
<variant-radios class="no-js-hidden" data-section="{{ section.id }}" data-url="{{ product.url }}" {{ block.shopify_attributes }}>
{%- for option in product.options_with_values -%}
<fieldset {% if option_name contains option.name %} class="swatchComponent" style=" padding: 0;" {% else %} class="js product-form__input" style="border:none" {% endif %}>
{% if option_name contains option.name %}
<legend class="form__label">{{ option.name }}<color-name></color-name></legend>
<div class="swatchContainer">
{% assign productVariantImage = "" %}
{%- for value in option.values -%}
{%- for productOption in product.variants -%}
{%- if productOption.options[0] == value -%}
{% assign productVariantImage = productOption.featured_image %}
{%- endif -%}
{%- endfor -%}

<input class="inputColor"
name="{{ option.name }}"
value="{{ value | escape }}"
form="product-form-{{ section.id }}"
type="radio"
id="{{ section.id }}-{{ option.name }}-{{ forloop.index0 }}"
{% if option.selected_value == value %}checked{% endif %}>
<label class="labelColor"
for="{{ section.id }}-{{ option.name }}-{{ forloop.index0 }}"
data-color="{{value | downcase | replace: ' ', '-' }}"
style="
{% case swatch_shape %}
{% when 'round' %} border-radius: 50%; aspect-ratio: 1;
{% when 'square' %} aspect-ratio: 1;
{% when 'rectangle' %} height: calc({{swatch_size}} / 2);
{% when 'round-edge' %} border-radius: 15%; aspect-ratio: 1;
{% endcase %}">
<img src="{{- productVariantImage | img_url: 'small' | uniq -}}" alt="{{- productVariantImage.alt -}}">
</label>
{% endfor %}
</div>
{% else %}
<legend class="form__label">{{ option.name }}<color-name></color-name></legend>
{%- for value in option.values -%}
<input type="radio" id="{{ section.id }}-{{ option.name }}-{{ forloop.index0 }}"
name="{{ option.name }}"
value="{{ value | escape }}"
form="product-form-{{ section.id }}"
{% if option.selected_value == value %}checked{% endif %}>
<label for="{{ section.id }}-{{ option.name }}-{{ forloop.index0 }}">
{{ value }}
</label>
{%- endfor -%}
{% endif %}
</fieldset>
{% endfor -%}
<script type="application/json">
{{ product.variants | json }}
</script>
</variant-radios>
{%- else -%}

<variant-selects class="no-js-hidden" data-section="{{ section.id }}" data-url="{{ product.url }}" {{ block.shopify_attributes }}>
{%- for option in product.options_with_values -%}
{% if option_name contains option.name %}
<variant-color>
<fieldset class="swatchComponent" style=" padding: 0;">

<legend class="form__label">{{ option.name }}<color-name></color-name></legend>
<div class="swatchContainer">
{% assign productVariantImage = "" %}
{%- for value in option.values -%}
{%- for productOption in product.variants -%}
{%- if productOption.options[0] == value -%}
{% assign productVariantImage = productOption.featured_image %}
{%- endif -%}
{%- endfor -%}
<input class="inputColor"
name="{{ option.name }}"
value="{{ value | escape }}"
form="product-form-{{ section.id }}"
type="radio"
id="{{ section.id }}-{{ option.name }}-{{ forloop.index0 }}"
{% if option.selected_value == value %}checked{% endif %}>
<label class="labelColor"
for="{{ section.id }}-{{ option.name }}-{{ forloop.index0 }}"
style="
{% case swatch_shape %}
{% when 'round' %} border-radius: 50%; aspect-ratio: 1;
{% when 'square' %} aspect-ratio: 1;
{% when 'rectangle' %} height: calc({{swatch_size}} / 2);
{% when 'round-edge' %} border-radius: 15%; aspect-ratio: 1;
{% endcase %}">
<img src="{{- productVariantImage | img_url: 'small' | uniq -}}" alt="{{- productVariantImage.alt -}}">
</label>
{% endfor %}
</div>

</fieldset>
</variant-color>
{% endif %}

<div class="product-form__input product-form__input--dropdown" {% if option_name contains option.name %}style="display: none"{% endif %}>
<label class="form__label" for="Option-{{ section.id }}-{{ forloop.index0 }}">
{{ option.name }}
</label>
<div class="select">
<select id="Option-{{ section.id }}-{{ forloop.index0 }}"
class="select__select {% if option_name contains option.name %} colorSelect{% endif %}"
name="options[{{ option.name | escape }}]"
form="{{ product_form_id }}">
{%- for value in option.values -%}
<option value="{{ value | escape }}" {% if option.selected_value == value %}selected="selected"{% endif %}>
{{ value }}
</option>
{%- endfor -%}
</select>
{% render 'icon-caret' %}
</div>
</div>
{%- endfor -%}
<script type="application/json">
{{ product.variants | json }}
</script>
</variant-selects>
{%- endif -%}
{%- endunless -%}
<noscript class="product-form__noscript-wrapper-{{ section.id }}">
<div class="product-form__input{% if product.has_only_default_variant %} hidden{% endif %}">
<label class="form__label" for="Variants-{{ section.id }}">{{ 'products.product.product_variants' | t }}</label>
<div class="select">
<select name="id" id="Variants-{{ section.id }}" class="select__select" form="{{ product_form_id }}">
{%- for variant in product.variants -%}
<option
{% if variant == product.selected_or_first_available_variant %}selected="selected"{% endif %}
{% if variant.available == false %}disabled{% endif %}
value="{{ variant.id }}">
{{ variant.title }}
{%- if variant.available == false %} - {{ 'products.product.sold_out' | t }}{% endif %}
- {{ variant.price | money | strip_html }}
</option>
{%- endfor -%}
</select>
{% render 'icon-caret' %}
</div>
</div>
</noscript>
<script>
class VariantColor extends HTMLElement {
constructor() {
super();
this.inputColors = this.querySelectorAll('.inputColor');
this.inputColors.forEach(color => color.addEventListener('click', this.colorSelected.bind(this)));
}

colorSelected(event) {
const select = document.querySelector(`.colorSelect`);
const item = event.currentTarget.value;
select.value = item ;
}
}

customElements.define('variant-color', VariantColor);
</script>
<style>
fieldset{
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
}

.swatchComponent {
display: flex;
margin: 5% 0;
box-sizing: border-box;
position: relative;
border: none;
}

.swatchContainer {
display: flex;
flex-wrap: wrap;
width: 100%;
}

.inputColor {
display: none;
}

.labelColor {
width: {{swatch_size}};
margin: 1%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
overflow: hidden;
transition: all .3s ease;
}

.labelColor:hover{
transform: scale(1.1);
}

.labelColor img {
object-fit: cover;
width: 100%;
}

.inputColor:checked + .labelColor + .infoColor {
display: flex;
}

.inputColor:checked + .labelColor {
outline: 2px solid;
border: 2px solid white;
}
</style>

 

5. Showing pictures of the variant color will not be enough, we have to provide the name of the color variant they are choosing. Therefore, we need the script below. Go to global.js under the Asset folder and add the code below. 

class ColorName extends HTMLElement {
constructor() {
super();
this.color = this.parentNode.innerText;
this.optionSelects = this.parentNode.parentNode;
this.optionSelects.addEventListener('change', this.colorRender.bind(this))
this.colorRender();
}

colorRender() {
this.selectedColor = document.querySelector(`input[name="${this.color}"]:checked`).value;
this.innerText = `: ${this.selectedColor.charAt(0).toUpperCase() + this.selectedColor.slice(1)}`;
}
}

customElements.define('color-name', ColorName);

 

If you want to show the swatch to a product card then proceed with the following steps.

6. Open the card-product.liquid under the Snippet folder. Then find the "card-information". There are two of them, make sure it is the first one. Paste the code below before the "card-information. Click enter to start a new line. See the image below for placement. 

code placement

 {% comment %} ============================================================================================================= {% endcomment %}
{% assign colorName = "Color" %} {% comment %} Provide the name of the Color. Make sure you enclose it with quotation marks {% endcomment %}
{% assign swatchSize = '4rem' %} {% comment %} You can use rem, px, %, etc. Make sure you enclose it with quotation marks {% endcomment %}
{% comment %} ============================================================================================================= {% endcomment %}
{%- for option in card_product.options_with_values -%}
{% if option.name == colorName %}
<fieldset class="js product-form__input">
<legend>{{ option.name }}</legend>
{%- for value in option.values limit: 5 -%}
<input type="radio" id="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}"
name="{{ option.name }}"
value="{{ value | escape }}"
form="{{ product_form_id }}"
{% if option.selected_value == value %}checked{% endif %}>
<label for="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}"
class="{% if option.name == colorName %}colorLabel{% endif %}">
{% if option.name == colorName %}
{%- for productOption in card_product.variants -%}
{%- if productOption.options[0] == value and productOption.featured_image != blank -%}

<img src="{{- productOption.featured_image | img_url: 'small' | uniq -}}" alt="{{- productOption.featured_image.alt -}}">
{%- endif -%}
{%- endfor -%}
{% endif %}
</label>
{%- endfor -%}

{% if option.values.size > 5 %}<strong class="plusMore"> + More </strong>{% endif %}

</fieldset>
{% endif %}

{% endfor %}
<script type="application/json">
{{ card_product.variants | json }}
</script>
<style scoped>
fieldset {
border: none;
padding: 0;
}


.colorLabel {
padding: 0 !important;
height: calc({{swatchSize}} + var(--variant-pills-border-width));
aspect-ratio: 1;
border: var(--variant-pills-border-width) solid transparent !important;
border-radius: 50%;
overflow: hidden;
display: inline-block;
margin: 0.7rem 0.5rem 0.2rem 0;
transition: border var(--duration-short) ease;
cursor: pointer;
position: relative;
}

.colorLabel:before {
content: "";
position: absolute;
top: calc(var(--variant-pills-border-width) * -1);
right: calc(var(--variant-pills-border-width) * -1);
bottom: calc(var(--variant-pills-border-width) * -1);
left: calc(var(--variant-pills-border-width) * -1);
z-index: -1;
border-radius: var(--variant-pills-radius);
box-shadow: var(--variant-pills-shadow-horizontal-offset) var(--variant-pills-shadow-vertical-offset) var(--variant-pills-shadow-blur-radius) rgba(var(--color-shadow),var(--variant-pills-shadow-opacity));
}

.product-form__input input[type=radio] {
clip: rect(0,0,0,0);
overflow: hidden;
position: absolute;
height: 1px;
width: 1px;
}

fieldset label > img {
width: {{swatchSize}};
height: {{swatchSize}};
aspect-ratio: 1;
}

fieldset label > img:not(:first-child) {
display: none !important;
}

.plusMore {
display: inline-block;
top: -13px;
position: relative;
}
</style>

 

Note: Dawn theme has a lot of edits, some old version of Dawn they call the product using "product_card", the latest version, which I use in this tutorial, uses "card_product."

Depending on your Dawn version, you have to change the some of the code in Step 6. To see if you have product_card or card_product, you can check it on the card_product.liquid. See image below. 

If you do not have card_product, you can change the code by simply have to click Ctrl + F, and find "card_product", and change it to product_card. 

card_product or product_card

 

That's it (",)

Copied!
Voltar para o blogue

Deixe um comentário