WooCommerce Product Loop

Custom WooCommerce product loop with sale badge and quick view.

Completely customizes the WooCommerce product loop with sale percentage badges, quick view buttons, hover effects, and modern card design. Includes all necessary CSS styling.
woocommerce-custom-loop.phpphp
<?php
/**
 * Custom WooCommerce Product Loop
 * Replace default product loop with custom design
 */

// Remove default WooCommerce hooks
remove_action('woocommerce_before_shop_loop_item', 'woocommerce_template_loop_product_link_open', 10);
remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_product_link_close', 5);
remove_action('woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10);
remove_action('woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating', 5);
remove_action('woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10);
remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10);

// Add custom product card
add_action('woocommerce_before_shop_loop_item', 'custom_product_card_start', 10);
add_action('woocommerce_before_shop_loop_item_title', 'custom_product_image', 10);
add_action('woocommerce_shop_loop_item_title', 'custom_product_title', 10);
add_action('woocommerce_after_shop_loop_item_title', 'custom_product_price', 10);
add_action('woocommerce_after_shop_loop_item', 'custom_product_card_end', 10);

function custom_product_card_start() {
    global $product;
    echo '<div class="custom-product-card">';
    echo '<a href="' . get_permalink() . '" class="product-link">';
}

function custom_product_image() {
    global $product;
    
    echo '<div class="product-image-wrapper">';
    
    // Sale badge
    if ($product->is_on_sale()) {
        $percentage = round((($product->get_regular_price() - $product->get_sale_price()) / $product->get_regular_price()) * 100);
        echo '<span class="sale-badge">-' . $percentage . '%</span>';
    }
    
    // Product image
    echo woocommerce_get_product_thumbnail('medium');
    
    // Quick view button
    echo '<button class="quick-view-btn" data-product-id="' . $product->get_id() . '">Quick View</button>';
    
    echo '</div>';
}

function custom_product_title() {
    echo '<h3 class="product-title">' . get_the_title() . '</h3>';
}

function custom_product_price() {
    global $product;
    echo '<div class="product-price">' . $product->get_price_html() . '</div>';
    
    // Add to cart button
    echo '<button class="add-to-cart-btn" data-product-id="' . $product->get_id() . '">Add to Cart</button>';
}

function custom_product_card_end() {
    echo '</a></div>';
}

/**
 * Add custom CSS
 */
function custom_product_loop_styles() {
    ?>
    <style>
    .custom-product-card {
        position: relative;
        border: 1px solid #e5e5e5;
        border-radius: 12px;
        overflow: hidden;
        transition: all 0.3s ease;
    }
    
    .custom-product-card:hover {
        box-shadow: 0 8px 24px rgba(0,0,0,0.1);
        transform: translateY(-4px);
    }
    
    .product-image-wrapper {
        position: relative;
        overflow: hidden;
    }
    
    .sale-badge {
        position: absolute;
        top: 12px;
        right: 12px;
        background: #ef4444;
        color: white;
        padding: 6px 12px;
        border-radius: 6px;
        font-size: 12px;
        font-weight: 700;
        z-index: 2;
    }
    
    .quick-view-btn {
        position: absolute;
        bottom: 12px;
        left: 50%;
        transform: translateX(-50%) translateY(100%);
        background: white;
        border: none;
        padding: 10px 20px;
        border-radius: 6px;
        font-weight: 600;
        cursor: pointer;
        transition: all 0.3s ease;
        opacity: 0;
    }
    
    .custom-product-card:hover .quick-view-btn {
        transform: translateX(-50%) translateY(0);
        opacity: 1;
    }
    
    .product-title {
        padding: 16px;
        font-size: 16px;
        font-weight: 600;
        margin: 0;
    }
    
    .product-price {
        padding: 0 16px;
        font-size: 18px;
        font-weight: 700;
    }
    
    .add-to-cart-btn {
        width: calc(100% - 32px);
        margin: 16px;
        padding: 12px;
        background: #000;
        color: white;
        border: none;
        border-radius: 6px;
        font-weight: 600;
        cursor: pointer;
        transition: background 0.3s;
    }
    
    .add-to-cart-btn:hover {
        background: #333;
    }
    </style>
    <?php
}
add_action('wp_head', 'custom_product_loop_styles');

Usage

Add to functions.php to override default WooCommerce product display

Installation

Add to theme's functions.php

Let’s Build Something You’ll Be Proud Of

No fluff. Just thoughtful design and reliable development.

Work with me
Average response time: within 24 hours