Shopify has been adding some cool new features this year, like letting you show product colors with swatches on the product page. This feature is supposed to be available to everyone by now, but it seems like it’s still under wraps. We hear you! That’s why we put together this guide to help you add color swatches to your store, even if you’re on theme version 13.0.1.
Step 1: Add code in settings_schema.json
Add the following code in settings_schema.json
{
"name": "Color Swatches by WebSensePro",
"settings": [
{
"type": "paragraph",
"content": "Support WebSensePro by [Subscribing our Channel](https:\/\/youtube.com\/@websensepro?sub_confirmation=1)"
},
{
"type": "text",
"id": "optionName",
"label": "Swatch option name",
"default": "Color",
"info": "Make sure capitalization is same as variant for e.g Color not color "
},
{
"type": "paragraph",
"content": "If your store is in different languages, type in all the different words and separate them with commas. For example: Color, Colour, Couleur"
},
{
"type": "select",
"id": "swatchType",
"label": "Swatch type",
"options": [
{
"value": "color",
"label": "Color"
},
{
"value": "variantImage",
"label": "Variant image"
}
],
"default": "color"
},
{
"type": "textarea",
"id": "swatchColors",
"label": "Colors",
"placeholder": "Red:#ff0000\nGreen:#00ff00\nBlue:#0000ff",
"default": "Black:#000000\nWhite:#f5f5f5\nBlue:#005eff\nRed:#c9002c\nPink:#ffd5e6\nBrown:#a2896b\nOlive:#808000\nGreenRed:#008000#c9002c\nGreenRedBlue:#008000#c9002c#005eff",
"info": "One rule per line. Example: Blue:#005eff\n2 Color Swatch Example: GreenRed:#008000#c9002c\n3 Color Swatch Example: GreenRedBlue:#008000#c9002c#005eff"
},
{
"type": "paragraph",
"content": "You can also add [image files](\/admin\/content\/files?selectedView=all&media_type=Image) instead of using colors, in lowercase with spaces replaced by hyphens. Example: Green kaki: green-kaki.png"
},
{
"type": "select",
"id": "swatchStyle",
"label": "Swatch style",
"options": [
{
"value": "round",
"label": "Round"
},
{
"value": "square",
"label": "Square"
},
{
"value":"square-round-corners",
"label":"Square round corners"
},
{
"value": "portrait",
"label": "Portrait"
}
],
"default": "round",
"info":"Portrait mode is only available for the variant image type."
},
{
"type": "range",
"id": "swatchSize",
"min": 20,
"max": 120,
"step": 2,
"unit": "px",
"label": "Swatch size",
"default": 40
}
]
},
Step 2: Replace Code in product-variant-picker
Please replace the code on line 52 of the file named “product-variant-picker.liquid”:
<fieldset class="js product-form__input product-form__input--pill">
<legend class="form__label">{{ option.name }}</legend>
{% render 'product-variant-options',
product: product,
option: option,
block: block,
picker_type: picker_type
%}
</fieldset>
With the following code:
<fieldset class="js product-form__input product-form__input--pill">
{%- liquid
assign optionNames = settings.optionName | split:","
assign useColor = false
for optionColor in optionNames
if optionColor == option.name
assign useColor = true
break
endif
endfor
-%}
{%- if useColor -%}
<legend class="form__label ">{{ option.name }}:<span id="selected-{{ option.name }}"> {{ option.selected_value }}</span></legend>
{% render 'color-option', product: product, option: option, block: block %}
{%- else -%}
<legend class="form__label">{{ option.name }}</legend>
{% render 'product-variant-options', product: product, option: option, block: block, picker_type: picker_type %}
{%- endif -%}
</fieldset>
Step 3: Create A New Snippet File
Create new snippet file color-option.liquid
{% comment %}
Renders product variant options
Accepts:
- product: {Object} product object.
- option: {Object} current product_option object.
- block: {Object} block object.
Usage:
{% render 'product-variant-options',
product: product,
option: option,
block: block
%}
{% endcomment %}
{%- liquid
assign variants_available_arr = product.variants | map: 'available'
assign variants_option1_arr = product.variants | map: 'option1'
assign variants_option2_arr = product.variants | map: 'option2'
assign variants_option3_arr = product.variants | map: 'option3'
assign product_form_id = 'product-form-' | append: section.id
assign swatchType = settings.swatchType
assign swatchStyle = settings.swatchStyle
assign swatchSize = settings.swatchSize
assign swatchColors = settings.swatchColors | newline_to_br | split: '<br />'
-%}
<style>
.product-form__input input[type='radio'] + label.color-swatch,
.product-form__input input[type='radio'] + label.color-swatch:after,
.product-form__input input[type='radio'] + label.color-swatch:before{
border-radius: 0;
}
.product-form__input input[type='radio'] + label.color-swatch.round,
.product-form__input input[type='radio'] + label.color-swatch.round:after,
.product-form__input input[type='radio'] + label.color-swatch.round:before{
border-radius: 100%;
}
.product-form__input input[type='radio'] + label.color-swatch.round-corners,
.product-form__input input[type='radio'] + label.color-swatch.round-corners:after,
.product-form__input input[type='radio'] + label.color-swatch.round-corners:before{
border-radius: 5px;
}
.product-form__input input[type='radio'] + label.color-swatch{
border:1px rgb(214,214,214) solid;
width: {{swatchSize}}px;
height: {{swatchSize}}px;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
margin-right: 9px;
}
.product-form__input input[type='radio'] + label.color-swatch:before{
content: "";
position: absolute;
top: -1px;
left: -1px;
width: calc(100% + 2px);
height: calc(100% + 2px);
border: 1px rgb(214,214,214) solid;
z-index: 0;
}
.product-form__input input[type='radio'] + label.color-swatch:after{
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
{%- if settings.dark or swatchType == "variantImage" -%}
border: none;
{%- else -%}
border: 3px rgb(255 255 255) solid;
{%- endif -%}
}
.product-form__input input[type='radio'] + label.color-swatch:hover:before{
border: 1px rgb(125 124 124) solid;
}
.product-form__input input[type='radio']:checked + label.color-swatch:before{
{%- if settings.dark -%}
box-shadow: 0 0 0 2px rgb(var(--color-foreground));
{%- else -%}
box-shadow: 0 0 0 1px rgb(var(--color-foreground));
{%- endif -%}
border-color:rgb(var(--color-foreground));
}
.product-form__input input[type='radio'] + label.color-swatch.variant-swatch{
background-color:white;
{%- if swatchStyle == "portrait" -%}
height: calc({{swatchSize}}px/ 0.66);
{%- endif -%}
}
</style>
{%- for value in option.values -%}
{%- liquid
assign option_disabled = true
for option1_name in variants_option1_arr
case option.position
when 1
if variants_option1_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
assign option_disabled = false
endif
when 2
if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
assign option_disabled = false
endif
when 3
if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == product.selected_or_first_available_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
assign option_disabled = false
endif
endcase
endfor
-%}
{%- if block.settings.picker_type == 'button' -%}
<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 %}
{% if option_disabled %}
class="disabled"
{% endif %}
>
{%- if swatchType == "variantImage" -%}
<label
data-{{ option.name }}="{{value}}"
style="background-image:url(
{%- liquid
assign optionIndex = option.position | minus: 1
for variant in product.variants
if variant.options[optionIndex] == value
assign swatchSizePortrait = swatchSize | times: 2
echo variant.image | image_url: width: swatchSizePortrait
break
endif
endfor
-%}
);"
class="color-swatch variant-swatch {% case swatchStyle %}{% when "round" %}round{% when "square-round-corners" %}round-corners{% endcase %}"
for="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}">
<span class="visually-hidden">{{ 'products.product.variant_sold_out_or_unavailable' | t }}</span>
</label>
{%- else -%}
{%- liquid
for colorData in swatchColors
assign colorDataArr = colorData | split:":"
assign ruleName = colorDataArr[0] | strip
if value == ruleName
assign colorCodes = colorDataArr[1] | strip | split :"#"
assign colorNumber = 0 | plus: colorCodes.size
break
endif
endfor
-%}
<label
data-{{ option.name }}="{{value}}"
style="
{%- case colorNumber -%}
{%- when 2 -%}
background-color: #{{ colorCodes[1] }}
{%- when 3 -%}
background: linear-gradient(135deg, #{{ colorCodes[1] }} 50%, #{{ colorCodes[2] }} 50%);
{%- when 4 -%}
background: linear-gradient(to right,#{{ colorCodes[1] }} 33%,#{{ colorCodes[2] }} 33%,#{{ colorCodes[2] }} 66%, #{{ colorCodes[3] }} 66%);
{%- else -%}
background-image:url({{ colorCodes[0] | downcase | replace: ' ', '-' | file_img_url }})
{%- endcase -%}
;"class="color-swatch {% case swatchStyle %}{% when "round" %}round{% when "square-round-corners" %}round-corners{% endcase %}"
for="{{ section.id }}-{{ option.position }}-{{ forloop.index0 }}">
<span class="visually-hidden">{{ 'products.product.variant_sold_out_or_unavailable' | t }}</span>
</label>
{%- assign colorCodes = "" -%}
{%- endif -%}
{%- elsif block.settings.picker_type == 'dropdown' -%}
<option
value="{{ value | escape }}"
{% if option.selected_value == value %}
selected="selected"
{% endif %}
>
{% if option_disabled -%}
{{- 'products.product.value_unavailable' | t: option_value: value -}}
{%- else -%}
{{- value -}}
{%- endif %}
</option>
{%- endif -%}
{%- endfor -%}
<script>
document.querySelectorAll('input+label[data-{{ option.name | downcase }}]').forEach(el=>{
el.addEventListener('click',()=>{
document.querySelector('#selected-{{option.name}}').textContent = " "+el.getAttribute('data-{{ option.name | downcase }}')
})
})
</script>
3.7/5 - (68 votes)