When building an e-commerce site, few things are as painful as managing product variants. Sizes, colors, materials, fits—especially for apparel like men’s shorts. One wrong dropdown and a customer buys a size 30 waist when they wanted a 34. Let’s walk through a clean, flexible solution using vanilla JavaScript and a little CSS that keeps your variant selector sane.
We’ll use a simple product data structure for our men’s shorts collection. Imagine a product with three attributes: size (S, M, L), color (Black, Navy), and fit (Slim, Relaxed). We need to generate all valid combinations, then let the user pick one, updating price and stock.

First, define your variants as an array of objects. Each object has an id, attributes, price, and inStock boolean.
const variants = [
{ id: 1, attributes: { size: "S", color: "Black", fit: "Slim" }, price: 29.99, inStock: true },
{ id: 2, attributes: { size: "M", color: "Black", fit: "Slim" }, price: 29.99, inStock: true },
// ... more variants
];
Now, we need to dynamically generate the option selectors. Loop through the unique keys (size, color, fit) and create a <select> for each. When a user changes any selector, we filter the variants to find the one matching all current selections.
function getUniqueOptions(variants, key) {
return [...new Set(variants.map(v => v.attributes[key]))];
}
function updateVariant() {
const selected = {};
document.querySelectorAll('.variant-select').forEach(select => {
selected[select.dataset.attr] = select.value;
});
const match = variants.find(v =>
Object.keys(selected).every(key => v.attributes[key] === selected[key])
);
if (match) {
document.getElementById('price').textContent = `$${match.price.toFixed(2)}`;
document.getElementById('stock').textContent = match.inStock ? 'In Stock' : 'Out of Stock';
}
}
For the HTML, wrap each selector in a label:
<label>Size: <select class="variant-select" data-attr="size">...</select></label>
This approach is lightweight, avoids heavy frameworks, and scales to any number of attributes. You can easily extend it to show images per color or disable out-of-stock options.
If you want a live example, I built this for a men’s shorts collection at Frishay where we have dozens of variants per product. The logic stays the same—just the data gets bigger.
Building your own variant picker gives you full control over UX and performance. No bloated plugins, just clean, maintainable code. Give it a try in your next project.
Top comments (1)
Great point! I've found that consistency matters more than intensity when building habits. What's one small change that made the biggest impact for you?