Shopify Product Showcase – Feature-Rich Product Grid & Slider

Add a versatile product showcase to your Shopify store with customizable product cards, ratings, quantity selectors, and add-to-cart functionality. Features responsive design with desktop grid and mobile slider views.
Liquid Code
<!-- ======================================== Section Name: Product Showcase Tech Stack: Liquid, HTML, CSS, JavaScript, Swiper.js What This Section Does: - Displays a customizable grid of product cards with detailed information and functionality. - Features product badges, ratings, pricing with compare-at options, and shipping information. - Includes quantity selectors with dynamic price updates and direct add-to-cart functionality. - Fully responsive with desktop grid and mobile swiper layouts for optimal viewing experience. Promotion: Enhance your Shopify store with a professional product showcase section. Highlight featured products with rich details and seamless shopping experience. Get it now at [PrebuiltTemplates](https://prebuilttemplates.com/). ======================================== --> {% comment %} Section: Custom Product Showcase A grid of selected products with dynamic data rendering and mobile swiper {% endcomment %} <section class="product-showcase-section-{{ section.id }}" style="background-color: {{ section.settings.bg_color }}; padding: {{ section.settings.pad_top }}px 0 {{ section.settings.pad_bot }}px;"> <div class="product-showcase-container page-width"> {% if section.settings.title != blank %} <h2 class="product-showcase-heading">{{ section.settings.title }}</h2> {% endif %} {% if section.settings.description != blank %} <div class="product-showcase-description">{{ section.settings.description }}</div> {% endif %} <!-- Desktop/Tablet View --> <div class="product-showcase-grid desktop-grid" style="grid-template-columns: repeat({{ section.settings.columns_desktop }}, 1fr);"> {% for block in section.blocks %} {% if block.type == 'product' %} {% assign product = all_products[block.settings.product] %} {% if product != blank %} {% assign current_variant = product.selected_or_first_available_variant %} <div class="product-showcase-item" {{ block.shopify_attributes }}> <div class="product-showcase-card"> {% if block.settings.show_badge %} <div class="product-badge" style="background-color: {{ block.settings.badge_color }};"> <span>{{ block.settings.badge_text }}</span> </div> {% endif %} <div class="product-showcase-images"> <a href="{{ product.url }}" class="product-image-link"> {% if product.featured_image != blank %} <img class="product-showcase-image" src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.featured_image.alt | default: product.title | escape }}"> {% else %} {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }} {% endif %} </a> </div> <div class="product-showcase-info"> <p class="product-vendor">{{ product.vendor }}</p> <h3 class="product-showcase-title"> <a href="{{ product.url }}">{{ product.title }}</a> </h3> <p class="product-showcase-description"> {{ product.description | strip_html | truncatewords: 15 }} </p> <div class="product-showcase-rating" style="--rating: {{ block.settings.rating }};"> <div class="rating-stars"> <span>★★★★★</span> </div> <span class="rating-count">{{ block.settings.review_count }} Reviews</span> </div> <div class="product-showcase-pricing" data-price="{{ current_variant.price | divided_by: 100.00 }}"> {% if current_variant.compare_at_price > current_variant.price %} <span class="product-showcase-price-old">${{ current_variant.compare_at_price | divided_by: 100.00 }}</span> {% endif %} <span class="product-showcase-price">${{ current_variant.price | divided_by: 100.00 }}</span> </div> {% if block.settings.show_free_shipping %} <p class="product-showcase-shipping">{{ block.settings.shipping_text }}</p> {% endif %} <form method="post" action="/cart/add" id="product-form-{{ product.id }}-{{ section.id }}" accept-charset="UTF-8" class="product-form" enctype="multipart/form-data"> <input type="hidden" name="id" value="{{ current_variant.id }}"> <div class="product-showcase-actions"> <div class="quantity-selector"> <button type="button" class="quantity-button minus" aria-label="Decrease quantity">−</button> <input type="number" name="quantity" value="1" min="1" class="quantity-input" pattern="[0-9]*"> <button type="button" class="quantity-button plus" aria-label="Increase quantity">+</button> </div> <button type="submit" name="add" class="add-to-cart-button" style="background-color: {{ section.settings.button_color }}; color: {{ section.settings.button_text_color }};"> {{ section.settings.button_text }} </button> </div> </form> </div> </div> </div> {% else %} <div class="product-showcase-item" {{ block.shopify_attributes }}> <div class="product-showcase-card product-placeholder"> <div class="product-showcase-images"> {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }} </div> <div class="product-showcase-info"> <p class="product-vendor">Vendor Name</p> <h3 class="product-showcase-title">Product Title</h3> <p class="product-showcase-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vitae fermentum metus.</p> </div> </div> </div> {% endif %} {% endif %} {% endfor %} </div> <!-- Mobile Swiper View --> <div class="product-showcase-swiper mobile-swiper"> <div class="swiper-wrapper"> {% for block in section.blocks %} {% if block.type == 'product' %} {% assign product = all_products[block.settings.product] %} {% if product != blank %} {% assign current_variant = product.selected_or_first_available_variant %} <div class="swiper-slide" {{ block.shopify_attributes }}> <div class="product-showcase-card"> {% if block.settings.show_badge %} <div class="product-badge" style="background-color: {{ block.settings.badge_color }};"> <span>{{ block.settings.badge_text }}</span> </div> {% endif %} <div class="product-showcase-images"> <a href="{{ product.url }}" class="product-image-link"> {% if product.featured_image != blank %} <img class="product-showcase-image" src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.featured_image.alt | default: product.title | escape }}"> {% else %} {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }} {% endif %} </a> </div> <div class="product-showcase-info"> <p class="product-vendor">{{ product.vendor }}</p> <h3 class="product-showcase-title"> <a href="{{ product.url }}">{{ product.title }}</a> </h3> <p class="product-showcase-description"> {{ product.description | strip_html | truncatewords: 15 }} </p> <div class="product-showcase-rating" style="--rating: {{ block.settings.rating }};"> <div class="rating-stars"> <span>★★★★★</span> </div> <span class="rating-count">{{ block.settings.review_count }} Reviews</span> </div> <div class="product-showcase-pricing" data-price="{{ current_variant.price | divided_by: 100.00 }}"> {% if current_variant.compare_at_price > current_variant.price %} <span class="product-showcase-price-old">${{ current_variant.compare_at_price | divided_by: 100.00 }}</span> {% endif %} <span class="product-showcase-price">${{ current_variant.price | divided_by: 100.00 }}</span> </div> {% if block.settings.show_free_shipping %} <p class="product-showcase-shipping">{{ block.settings.shipping_text }}</p> {% endif %} <form method="post" action="/cart/add" id="product-form-mobile-{{ product.id }}-{{ section.id }}" accept-charset="UTF-8" class="product-form" enctype="multipart/form-data"> <input type="hidden" name="id" value="{{ current_variant.id }}"> <div class="product-showcase-actions"> <div class="quantity-selector"> <button type="button" class="quantity-button minus" aria-label="Decrease quantity">−</button> <input type="number" name="quantity" value="1" min="1" class="quantity-input" pattern="[0-9]*"> <button type="button" class="quantity-button plus" aria-label="Increase quantity">+</button> </div> <button type="submit" name="add" class="add-to-cart-button" style="background-color: {{ section.settings.button_color }}; color: {{ section.settings.button_text_color }};"> {{ section.settings.button_text }} </button> </div> </form> </div> </div> </div> {% else %} <div class="swiper-slide" {{ block.shopify_attributes }}> <div class="product-showcase-card product-placeholder"> <div class="product-showcase-images"> {{ 'product-1' | placeholder_svg_tag: 'product-showcase-placeholder' }} </div> <div class="product-showcase-info"> <p class="product-vendor">Vendor Name</p> <h3 class="product-showcase-title">Product Title</h3> <p class="product-showcase-description">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vitae fermentum metus.</p> </div> </div> </div> {% endif %} {% endif %} {% endfor %} </div> <div class="swiper-pagination"></div> </div> </div> </section> {% style %} .product-showcase-section-{{ section.id }} { overflow: hidden; } .product-showcase-container { max-width: 1200px; margin: 0 auto; padding: 0 20px; } .product-showcase-heading { font-size: 30px; margin-bottom: 15px; text-align: center; } .product-showcase-description { max-width: 800px; margin: 0 auto 40px; text-align: center; } .product-showcase-grid { display: grid; gap: 30px; } .product-showcase-item { transition: transform 0.3s ease; } .product-showcase-item:hover { transform: translateY(-8px); } .product-showcase-card { background-color: {{ section.settings.card_bg_color }}; border-radius: 12px; overflow: hidden; position: relative; box-shadow: 0 5px 15px rgba(0,0,0,0.05); padding: 30px; height: 100%; display: flex; flex-direction: column; } .product-placeholder { opacity: 0.7; } .product-badge { position: absolute; top: 20px; left: 20px; background-color: #009688; color: white; border-radius: 50%; width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 14px; z-index: 2; } .product-showcase-images { display: flex; justify-content: center; margin-bottom: 20px; } .product-image-link { display: block; text-align: center; overflow: hidden; } .product-showcase-image, .product-showcase-placeholder { max-width: 100%; height: auto; transition: transform 0.5s ease; } .product-image-link:hover .product-showcase-image { transform: scale(1.05); } .product-vendor { font-size: 14px; color: #666; margin-bottom: 5px; text-transform: uppercase; } .product-showcase-title { font-size: 24px; margin: 0 0 10px; font-weight: 700; color: #333; } .product-showcase-title a { color: inherit; text-decoration: none; } .product-showcase-description { font-size: 16px; color: #666; margin-bottom: 15px; line-height: 1.5; text-align: center; } .product-showcase-rating { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; } .rating-stars { position: relative; display: inline-block; color: #ddd; font-size: 18px; } .rating-stars::before { content: '★★★★★'; position: absolute; top: 0; left: 0; color: #009688; width: calc(var(--rating) * 20%); overflow: hidden; } .rating-count { font-size: 14px; color: #666; } .product-showcase-pricing { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } .product-showcase-price-old { text-decoration: line-through; color: #999; font-size: 16px; } .product-showcase-price { font-size: 24px; font-weight: 600; color: #333; } .product-showcase-shipping { font-size: 14px; color: #666; margin-bottom: 20px; } .product-showcase-actions { display: flex; flex-direction: column; gap: 15px; margin-top: auto; } .quantity-selector { display: flex; align-items: center; border: 1px solid #e0e0e0; border-radius: 30px; overflow: hidden; width: 100%; } .quantity-button { background: none; border: none; width: 40px; font-size: 18px; cursor: pointer; padding: 10px 0; color: #333; } .quantity-input { border: none; text-align: center; flex-grow: 1; padding: 12px 0; font-size: 16px; -moz-appearance: textfield; } .quantity-input::-webkit-inner-spin-button, .quantity-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } .add-to-cart-button { border: none; border-radius: 30px; padding: 15px; font-size: 16px; font-weight: 600; cursor: pointer; transition: opacity 0.2s ease; text-transform: uppercase; width: 100%; } .add-to-cart-button:hover { opacity: 0.9; } .product-form { width: 100%; } /* Swiper Styles */ .product-showcase-swiper { width: 100%; padding-bottom: 50px; display: none; } .swiper-slide { height: auto; } .swiper-pagination { bottom: 0; } .swiper-pagination-bullet-active { background-color: #009688; } @media screen and (max-width: 989px) { .product-showcase-grid { grid-template-columns: repeat({{ section.settings.columns_tablet }}, 1fr); } } @media screen and (max-width: 749px) { .desktop-grid { display: none; } .mobile-swiper { display: block; } .product-showcase-card { padding: 20px; } } {% endstyle %} <!-- Include Swiper JS --> <script src="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.css" /> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize Swiper for mobile if (window.innerWidth <= 749) { const swiper = new Swiper('.product-showcase-swiper', { slidesPerView: {{ section.settings.columns_mobile }}, spaceBetween: 20, pagination: { el: '.swiper-pagination', clickable: true, }, breakpoints: { 320: { slidesPerView: 1, }, 480: { slidesPerView: Math.min(2, {{ section.settings.columns_mobile }}), }, 640: { slidesPerView: {{ section.settings.columns_mobile }}, } } }); } // Quantity selector functionality for all products const quantitySelectors = document.querySelectorAll('.quantity-selector'); quantitySelectors.forEach(function(selector) { const minusButton = selector.querySelector('.minus'); const plusButton = selector.querySelector('.plus'); const input = selector.querySelector('.quantity-input'); // Update price based on quantity function updatePrice() { const form = selector.closest('.product-form'); const priceContainer = form.parentNode.querySelector('.product-showcase-pricing'); const priceDisplay = priceContainer.querySelector('.product-showcase-price'); const basePrice = parseFloat(priceContainer.getAttribute('data-price')); const quantity = parseInt(input.value, 10); const totalPrice = (basePrice * quantity).toFixed(2); priceDisplay.textContent = '$' + totalPrice; } minusButton.addEventListener('click', function() { const currentValue = parseInt(input.value, 10); if (currentValue > 1) { input.value = currentValue - 1; updatePrice(); } }); plusButton.addEventListener('click', function() { const currentValue = parseInt(input.value, 10); input.value = currentValue + 1; updatePrice(); }); input.addEventListener('change', function() { if (this.value < 1) { this.value = 1; } updatePrice(); }); }); // Handle window resize for responsive swiper window.addEventListener('resize', function() { if (window.innerWidth <= 749) { if (!document.querySelector('.swiper-initialized')) { const swiper = new Swiper('.product-showcase-swiper', { slidesPerView: {{ section.settings.columns_mobile }}, spaceBetween: 20, pagination: { el: '.swiper-pagination', clickable: true, }, breakpoints: { 320: { slidesPerView: 1, }, 480: { slidesPerView: Math.min(2, {{ section.settings.columns_mobile }}), }, 640: { slidesPerView: {{ section.settings.columns_mobile }}, } } }); } } }); }); </script> {% schema %} { "name": "Product Showcase", "settings": [ { "type": "range", "id": "pad_top", "label": "Padding Top", "min": 0, "max": 100, "step": 5, "default": 40 }, { "type": "range", "id": "pad_bot", "label": "Padding Bottom", "min": 0, "max": 100, "step": 5, "default": 40 }, { "type": "color", "id": "bg_color", "label": "Background Color", "default": "#f8f8f8" }, { "type": "color", "id": "card_bg_color", "label": "Card Background Color", "default": "#FFFFFF" }, { "type": "text", "id": "title", "label": "Section Title", "default": "Featured Products" }, { "type": "richtext", "id": "description", "label": "Section Description", "default": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>" }, { "type": "text", "id": "button_text", "label": "Add to Cart Button Text", "default": "ADD TO CART" }, { "type": "color", "id": "button_color", "label": "Button Background Color", "default": "#000000" }, { "type": "color", "id": "button_text_color", "label": "Button Text Color", "default": "#FFFFFF" }, { "type": "header", "content": "Layout" }, { "type": "range", "id": "columns_desktop", "label": "Columns (Desktop)", "min": 1, "max": 4, "step": 1, "default": 3 }, { "type": "range", "id": "columns_tablet", "label": "Columns (Tablet)", "min": 1, "max": 3, "step": 1, "default": 2 }, { "type": "range", "id": "columns_mobile", "label": "Columns (Mobile)", "min": 1, "max": 3, "step": 1, "default": 1 } ], "blocks": [ { "type": "product", "name": "Product", "settings": [ { "type": "product", "id": "product", "label": "Product" }, { "type": "checkbox", "id": "show_badge", "label": "Show Badge", "default": true }, { "type": "text", "id": "badge_text", "label": "Badge Text", "default": "15% OFF" }, { "type": "color", "id": "badge_color", "label": "Badge Color", "default": "#009688" }, { "type": "range", "id": "rating", "min": 0, "max": 5, "step": 0.1, "default": 4.8, "label": "Product Rating" }, { "type": "text", "id": "review_count", "label": "Review Count", "default": "42" }, { "type": "checkbox", "id": "show_free_shipping", "label": "Show Shipping Info", "default": true }, { "type": "text", "id": "shipping_text", "label": "Shipping Text", "default": "Free Oil + Free USA Shipping" } ] } ], "presets": [ { "name": "Product Showcase", "blocks": [ { "type": "product" }, { "type": "product" }, { "type": "product" } ] } ] } {% endschema %}