the problem with dropdowns
Shopify's default variant selector is a plain <select> dropdown. Colour swatches consistently outperform dropdowns for conversion rate — customers can see their options at a glance.
option data in liquid
{% for option in product.options_with_values %}
{% if option.name == 'Color' %}
<div class="swatch-row">
{% for value in option.values %}
<button class="swatch"
data-value="{{ value }}"
style="background-color: {{ value | downcase | replace: ' ', '-' }};"
aria-label="{{ value }}">
</button>
{% endfor %}
</div>
{% endif %}
{% endfor %}
mapping colours to swatches
The style approach works when colour names are valid CSS colour names or hex codes. For custom colours, use a Liquid case/when block to map option values to your actual hex codes.
image swatches
If you upload swatch images to the Files section named swatch-navy.png, etc., you can reference them with {{ value | downcase | append: '.png' | file_url }}. This is cleaner for complex patterns or gradient colours.
wiring up variant selection
On swatch click, update the hidden variant selector's value and trigger a change event. Most Shopify themes listen for this event to update price, images, and availability. No custom form handling needed.