Replace Quantity Input with Plus/Minus Buttons on Product Pages

Beginner
✓ Tested
📅 August 24, 2025
⬇️ 1 Downloads
📋 4 Copies

This snippet transforms the standard WooCommerce quantity number input into user-friendly plus and minus buttons, creating a modern and intuitive shopping experience that increases conversions, especially on mobile devices.

What does this code do?

Replaces the default number input field with elegant plus/minus buttons for quantity selection. The buttons automatically disable when reaching minimum or maximum quantities, and work seamlessly on both product pages and cart page.

Features:

  • Modern Design: Rounded buttons with smooth hover effects
  • Smart Validation: Respects min/max quantity limits
  • Mobile Optimized: Large touch-friendly buttons
  • Cart Integration: Auto-updates cart totals
  • Accessibility: Keyboard navigation maintained
  • Visual Feedback: Disabled state for limits
  • Smooth Animations: Scale effect on click

Where it works:

  • Single product pages
  • Cart page
  • Quick view modals
  • Grouped products
  • Variable products

Benefits:

  • Reduces input errors on mobile
  • Faster quantity selection
  • More intuitive for non-technical users
  • Improves conversion rates
  • Modern, professional appearance

⚠️ Important Warnings

⚠️ Some themes already have plus/minus buttons - check for conflicts
⚠️ May need CSS adjustments for custom themes
⚠️ Composite products might need additional compatibility code
⚠️ Some page builders override WooCommerce hooks
⚠️ Touch events on mobile might need fine-tuning
⚠️ Min/max quantities must be set correctly in products
⚠️ Cart page auto-update might conflict with some plugins
⚠️ Custom quantity rules plugins might not work properly
💻 PHP Code
/**
 * Add plus/minus buttons to WooCommerce quantity inputs
 * Replaces default number input with user-friendly buttons
 * Prefix: tpsc_ (TP Snippet Collection)
 */

// Add plus/minus buttons HTML
add_action('woocommerce_before_quantity_input_field', 'tpsc_quantity_minus_button');
add_action('woocommerce_after_quantity_input_field', 'tpsc_quantity_plus_button');

function tpsc_quantity_minus_button() {
    echo '<button type="button" class="tpsc-quantity-button tpsc-quantity-minus">-</button>';
}

function tpsc_quantity_plus_button() {
    echo '<button type="button" class="tpsc-quantity-button tpsc-quantity-plus">+</button>';
}

// Add CSS styling
add_action('wp_head', 'tpsc_quantity_buttons_styles');
function tpsc_quantity_buttons_styles() {
    if (!is_product() && !is_cart()) {
        return;
    }
    ?>
    <style>
        /* Container styling */
        .quantity {
            display: inline-flex !important;
            align-items: center;
            border: 2px solid #ddd;
            border-radius: 30px;
            overflow: hidden;
            background: #fff;
        }
        
        /* Hide number input spinners */
        .quantity input[type="number"]::-webkit-inner-spin-button,
        .quantity input[type="number"]::-webkit-outer-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
        
        .quantity input[type="number"] {
            -moz-appearance: textfield;
            border: none !important;
            text-align: center;
            width: 50px !important;
            padding: 12px 5px;
            font-size: 16px;
            font-weight: 600;
            background: transparent;
        }
        
        /* Plus/Minus buttons */
        .tpsc-quantity-button {
            background: #f7f7f7;
            border: none;
            width: 40px;
            height: 40px;
            cursor: pointer;
            font-size: 20px;
            font-weight: 600;
            color: #333;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0;
            line-height: 1;
        }
        
        .tpsc-quantity-button:hover {
            background: #333;
            color: #fff;
        }
        
        .tpsc-quantity-button:active {
            transform: scale(0.95);
        }
        
        .tpsc-quantity-button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        
        .tpsc-quantity-button:disabled:hover {
            background: #f7f7f7;
            color: #333;
        }
        
        /* Rounded corners */
        .tpsc-quantity-minus {
            border-radius: 30px 0 0 30px;
            border-right: 1px solid #ddd;
        }
        
        .tpsc-quantity-plus {
            border-radius: 0 30px 30px 0;
            border-left: 1px solid #ddd;
        }
        
        /* Cart page adjustments */
        .woocommerce-cart-form .quantity {
            margin: 0;
        }
        
        /* Mobile responsive */
        @media (max-width: 768px) {
            .quantity input[type="number"] {
                width: 40px !important;
                padding: 10px 2px;
            }
            
            .tpsc-quantity-button {
                width: 35px;
                height: 35px;
                font-size: 18px;
            }
        }
        
        /* Alternative style - Square buttons (uncomment to use) */
        /*
        .quantity {
            border-radius: 4px;
        }
        
        .tpsc-quantity-minus {
            border-radius: 4px 0 0 4px;
        }
        
        .tpsc-quantity-plus {
            border-radius: 0 4px 4px 0;
        }
        */
    </style>
    <?php
}

// Add JavaScript functionality
add_action('wp_footer', 'tpsc_quantity_buttons_script');
function tpsc_quantity_buttons_script() {
    if (!is_product() && !is_cart()) {
        return;
    }
    ?>
    <script>
    jQuery(document).ready(function($) {
        // Handle plus button click
        $(document).on('click', '.tpsc-quantity-plus', function(e) {
            e.preventDefault();
            
            var $input = $(this).closest('.quantity').find('input[type="number"]');
            var currentVal = parseInt($input.val()) || 0;
            var max = parseInt($input.attr('max')) || 9999;
            var step = parseInt($input.attr('step')) || 1;
            
            if (currentVal < max) {
                $input.val(currentVal + step).trigger('change');
            }
            
            updateButtonStates($input);
        });
        
        // Handle minus button click
        $(document).on('click', '.tpsc-quantity-minus', function(e) {
            e.preventDefault();
            
            var $input = $(this).closest('.quantity').find('input[type="number"]');
            var currentVal = parseInt($input.val()) || 0;
            var min = parseInt($input.attr('min')) || 1;
            var step = parseInt($input.attr('step')) || 1;
            
            if (currentVal > min) {
                $input.val(currentVal - step).trigger('change');
            }
            
            updateButtonStates($input);
        });
        
        // Update button states (disable when at min/max)
        function updateButtonStates($input) {
            var currentVal = parseInt($input.val()) || 0;
            var min = parseInt($input.attr('min')) || 1;
            var max = parseInt($input.attr('max')) || 9999;
            
            var $minus = $input.closest('.quantity').find('.tpsc-quantity-minus');
            var $plus = $input.closest('.quantity').find('.tpsc-quantity-plus');
            
            // Disable minus at minimum
            if (currentVal <= min) {
                $minus.prop('disabled', true);
            } else {
                $minus.prop('disabled', false);
            }
            
            // Disable plus at maximum
            if (currentVal >= max) {
                $plus.prop('disabled', true);
            } else {
                $plus.prop('disabled', false);
            }
        }
        
        // Initialize button states on load
        $('.quantity input[type="number"]').each(function() {
            updateButtonStates($(this));
        });
        
        // Update on manual input change
        $(document).on('change', '.quantity input[type="number"]', function() {
            updateButtonStates($(this));
        });
        
        // Trigger cart update on cart page
        if ($('body').hasClass('woocommerce-cart')) {
            $(document).on('change', '.quantity input[type="number"]', function() {
                $('[name="update_cart"]').prop('disabled', false).trigger('click');
            });
        }
    });
    </script>
    <?php
}

// Optional: Apply to cart page as well
add_filter('woocommerce_cart_item_quantity', 'tpsc_cart_quantity_buttons', 10, 3);
function tpsc_cart_quantity_buttons($product_quantity, $cart_item_key, $cart_item) {
    if (is_cart()) {
        return $product_quantity;
    }
    return $product_quantity;
}

📝 Installation Instructions

INSTALLATION:
1. Copy the entire code
2. Go to WordPress Admin → Appearance → Theme Editor → functions.php
3. Paste at the bottom of the file
4. Save changes
5. Visit a product page to see the new buttons

CUSTOMIZATION:

BUTTON STYLE:
Round buttons (default) or square buttons
- For square buttons: Uncomment lines 108-118

BUTTON SIZE:
Line 61: width: 40px; height: 40px;
- Increase for larger buttons
- Decrease for smaller buttons

COLORS:
Line 58: background: #f7f7f7; (button background)
Line 71: background: #333; (hover background)
Line 72: color: #fff; (hover text color)

SPACING:
Line 51: width: 50px (input field width)
Line 52: padding: 12px 5px (input padding)

DISABLE ON SPECIFIC PAGES:
To exclude from cart page, change line 24:
From: if (!is_product() && !is_cart())
To: if (!is_product())

TESTING:
1. Add product to cart with different quantities
2. Test min/max limits if set
3. Check cart auto-update works
4. Test on mobile devices
5. Verify keyboard navigation still works

TROUBLESHOOTING:
- If buttons don't appear: Check theme compatibility
- If styling is off: Add !important to CSS rules
- If cart doesn't update: Check AJAX settings

📸 Screenshots