In this tutorial, you’ll learn how to build a fully customizable Product Card Grid Section for your Shopify store — called the ZHD Product Card. This section will display your products beautifully with title, price, image, description, and buttons like Buy Now, Live Preview, and View Details.
We’ll walk through each step so you can add this section to your theme and control it directly from the Shopify theme editor.
🧰 What You’ll Need
- A Shopify theme (e.g., Dawn, Sense, or any Online Store 2.0 theme)
- Access to Edit Code in your theme
- A few products added to your store
⚙️ Step 1: Create the Section File
- Go to Online Store → Themes → Edit Code.
- In the Sections folder, click Add a new section.
- Name it:
zhd-product-card.liquid
💻 Step 2: Paste the Full Section Code
Copy and paste the entire code below into your new section file. This includes the HTML structure, CSS styling, JavaScript logic, and JSON schema.
<style>
.zhd__product-card {
padding: 10px;
max-width: 120rem;
margin: auto;
}
.zhd__product-card .zhd__product-card-card {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
max-width: 400px;
margin: 10px;
text-align: center;
}
.zhd__product-card h4.zhd__product-card-title {
font-size: 16px;
margin: 0;
padding: 20px 15px 5px 15px;
cursor: pointer;
}
.zhd__product-card .zhd__product-card-description p {
font-size: 14px;
color: #0000008f;
margin: 0;
padding: 5px 15px;
}
.zhd__product-card .zhd__product-card-price {
color: #00B9BB;
font-size: 18px;
}
.zhd__product-card span.compare_at_price {
text-decoration: line-through;
color: gray;
}
.zhd__product-card .zhd__product-card-btn-live-url,
.zhd__product-card .zhd__product-card-btn-view-details,
.zhd__product-card .zhd__product-card-btn-buy-now{
border: none;
outline: 0;
padding: 12px;
cursor: pointer;
display: block;
font-size: 18px;
width: 100%;
margin-bottom: -10px;
}
.zhd__product-card .zhd__product-card-btn-live-url{color: #fff;background-color: #1e293b;}
.zhd__product-card .zhd__product-card-btn-view-details{color: #fff;background-color: #00B9BB;}
.zhd__product-card .zhd__product-card-btn-buy-now{color: #00B9BB;background-color: #f4f6f8;}
.zhd__product-card .zhd__product-card-btn-live-url:hover,
.zhd__product-card .zhd__product-card-btn-view-details:hover,
.zhd__product-card .zhd__product-card-btn-buy-now:hover{
opacity: 0.7;
}
#product-img-scroll{transition: ease-in-out 4s;}
#product-img-scroll:hover{background-position: center bottom;}
.zhd__product-card .zhd__product-card-flex-container {
display: flex; flex-wrap: wrap; flex-direction: row; text-align: center;
}
.zhd__product-card .zhd__product-card-flex-item { padding: 10px; flex: 30%; }
.priceFreeTag {
font-size: 20px;
font-weight: bold;
color: red;
animation: blink 2s infinite;
border: 1px dashed red;
padding: 4px;
}
@keyframes blink { 50% { opacity: 0; } }
@media (max-width: 800px) {
.zhd__product-card .zhd__product-card-flex-container { flex-direction: column; }
}
</style>
<div class="zhd__product-card">
<div class="zhd__product-card-flex-container">
{% for block in section.blocks %}
{%- assign product = all_products[block.settings.card_product] -%}
<div class="zhd__product-card-flex-item">
<div class="zhd__product-card-card">
<div
id="product-img-scroll"
style="width:100%; height:400px;
background:url({{ product.featured_image | image_url }});
background-size:cover; background-position:top;"
>.</div>
<h4 class="zhd__product-card-title">{{ product.title | truncatewords: 4 }}</h4>
{% if block.settings.price_show %}
<p class="zhd__product-card-price">
<span class="compare_at_price">{{ product.compare_at_price | money }}</span>
{% if product.price == 0 %}
<span class="priceFreeTag">Free</span>
{% else %}
{{ product.price | money_without_trailing_zeros }}
{% endif %}
</p>
{% endif %}
{% if block.settings.productDescription_show %}
<div class="zhd__product-card-description">{{ product.description | truncatewords: 13 }}</div>
{% endif %}
{% if block.settings.livebtn_show %}
<p><a class="zhd__product-card-btn-live-url" target="_blank" href="{{ block.settings.live_url }}">Live Preview</a></p>
{% endif %}
{% if block.settings.viewbtn_show %}
<p><a class="zhd__product-card-btn-view-details" href="{{ product.url }}">View Details</a></p>
{% endif %}
<form method="post" action="/cart/add" class="product-form">
<input type="hidden" name="id" value="{{ product.variants.first.id }}">
{% if product.price == 0 %}
<button type="submit" class="zhd__product-card-btn-buy-now" id="buy-it-now">Download</button>
{% else %}
<button type="submit" class="zhd__product-card-btn-buy-now" id="buy-it-now">Buy</button>
{% endif %}
</form>
</div>
</div>
{% endfor %}
</div>
</div>
<script>
document.querySelectorAll("#buy-it-now").forEach(button => {
button.addEventListener("click", (e) => {
e.preventDefault();
var form = e.target.closest("form");
var input = document.createElement("input");
input.type = "hidden";
input.name = "return_to";
input.value = "/checkout";
form.appendChild(input);
form.submit();
});
});
</script>
{% schema %}
{
"name": "ZHD product card",
"settings": [],
"blocks": [
{
"type": "product-card",
"name": "product card",
"limit": 20,
"settings": [
{"type": "checkbox","id": "price_show","label": "Show Price?","default": true},
{"type": "checkbox","id": "productDescription_show","label": "Show Description?","default": true},
{"type": "checkbox","id": "livebtn_show","label": "Live Btn Show?","default": true},
{"type": "checkbox","id": "viewbtn_show","label": "View Btn Show?","default": true},
{"type": "product","id": "card_product","label": "Product"},
{"type": "text","id": "live_url","label": "Store Link"}
]
}
],
"presets": [
{"name": "ZHD product card","blocks": [{"type": "product-card"}]}
]
}
{% endschema %}
🎨 Step 3: Add the Section in Theme Editor
- Go back to your Theme Editor → click Add Section.
- Find and add ZHD Product Card.
- Under Block Settings, select your products and toggle:
- Show Price / Description
- Show Buttons (Live Preview, View Details, Buy)
- Add custom Live URL (e.g., demo link)
🧲 Step 4: Preview and Test
Click Save → Preview. You’ll see a responsive grid of product cards — with scrolling images, blinking “Free” tags, and quick checkout buttons.
When you click Buy or Download, it automatically redirects users to checkout.
💡 Bonus Ideas
- Change card shadow or hover animations.
- Add ratings or badges with metafields.
- Make “Live Preview” button open a modal or embedded demo.
✅ Final Result
You’ve now built a professional Shopify Product Card Section — reusable, dynamic, and fully editable without touching code again. It’s perfect for showcasing featured products, digital downloads, or portfolio items.
Pro Tip: Combine this section with Shopify’s metafields or dynamic sources for advanced automation!
Written by Zahidul Islam | Shopify Custom Design Tutorials