Product Variation Radio Buttons
Replace the WooCommerce product variation drop-downs with user-focused, mobile-friendly radio/pill buttons. Create a cleaner product page and boost the user experience of your store!
Licences for this plugin last forever 😀

100% No-Risk, Money Back Guarantee!
Over the next 14 days, if any Power Plugins aren’t the best fit for your project, just reach out! We’ll refund 100% of your money.
No questions asked!
- Description
- Styling the Buttons
- Enable Dynamically
- Image Swatches
- Actions & Filters
- Changelog
- Reviews (2)
About Product Variation Radio Buttons
Replace the default WooCommerce variable-product drop-down lists with elegant radio buttons (pills).
Just activate the plugin and you’re away – it works straight out of the box.
- Works out of the box
- Easy to theme
- Developer friendly
- Multiple variation attributes
- Great on mobile devices
Variation radio buttons on real sites


Styling the Buttons
The easiest way to configure the pill button colours is to to go Settings > Product Variation Pills and check the “Configure the pill colours here” option.
Each button has three states it can be in:
- Off / unselected
- On / Selected
- Hover
Manual Styling Using CSS
Here’s a simple example of how to style the pills themselves. Either copy-and-paste this into your custom child theme’s style.css file, or paste it into the Additional CSS in the Customizer. Change the colours to suit your site.
/* Unselected / off */ .pv-pills .pill { border: 1px solid grey; border-radius: 0.5em; transition: 0.3s background-color; } /* Selected / on */ .pv-pills .pill input[type="checkbox"]:checked+label { background-color: purple; color: white; } /* Hover */ .pv-pills .pill label:hover { border: 1px solid black; }
Enable / Disable Pills Dynamically
If you need to disable Product Variation Pills for one or more of your products, you can hook the pvp_is_active
filter. Copy and paste this example into your custom child theme’s functions.php and change the values in $disable_for_ids
for your products.
/** * COnditionally disable PV Pills for some products. */ function custom_pvp_is_active($is_active) { $product = get_product(); // Product IDs where you don't want Product Variation Pills. $disable_for_ids = array(1234, 9876); if (in_array($product->get_id(), $disable_for_ids)) { $is_active = false; } return $is_active; } add_filter('pvp_is_active', 'custom_pvp_is_active');
Product Variation Swatches
Use the pvpill_label_html to modify the radio button labels and inject image swatches.
In your custom child theme, create a file called pv-pills-swatches.php and paste the following into it.
<?php /** * Product Variation Radio Button Swatches (PVRBS) * * https://power-plugins.com/plugin/product-variation-pills/ */ defined('WPINC') || die(); /** * A : Replace the radio buttons with images * B : Add image after the label * C : Insert image before the label */ const PVRBS_IMAGE_SWATCH_POSITION = 'A'; /** * An array of product attributes that have image swatches. */ const PVRBS_IMAGE_SWATCH_ATTRIBUTES = array( 'pa_size', // 'pa_style', // 'pa_length', // etc... ); /** * Render an image in the radio button for some product attribute terms. * * @param string $label_html The internal HTML for the dario button * @param WP_Term $term The term for the button being rendered * @param string $attribute_name Includes the "pa_" prefix * */ function pvrbs_get_label_html($label_html, $term, $attribute_name) { if (in_array($attribute_name, PVRBS_IMAGE_SWATCH_ATTRIBUTES)) { $theme_version = wp_get_theme()->get('Version'); $base_uri = get_stylesheet_directory_uri(); $image_html = sprintf( '<img src="%s" alt="%s" title="%s" />', esc_url($base_uri . '/pv-pills-swatches/' . $attribute_name . '-' . $term->slug . '.png'), esc_attr($term->name), // Image alt text esc_attr($term->name) // Mouse-hover tooltip ); if (PVRBS_IMAGE_SWATCH_POSITION == 'A') { $label_html = $image_html; } elseif (PVRBS_IMAGE_SWATCH_POSITION == 'B') { $label_html .= $image_html; } elseif (PVRBS_IMAGE_SWATCH_POSITION == 'C') { $label_html = $image_html . $label_html; } else { // Unknown swatch position } } return $label_html; } add_filter('pvpill_label_html', 'pvrbs_get_label_html', 10, 3);
Next, edit your child theme’s “functions.php” file and add the following couple of lines.
// Swatches for Product Variation Radio Buttons require_once dirname(__FILE__) . '/pv-pills-swatches.php';
If a label’s $attribute_name is in the PVRBS_IMAGE_SWATCH_ATTRIBUTES array, it creates an image URL based in your child theme like this:
wp-content/mytheme/pv-pills-swatches/pa_size-small.png
…where the file name part is:
$attribute_name "-" $term->slug ".png"
Then all you need to do is create a folder in your child theme called “pv-pills-swatches” and place your swatch images in there.
If you want to set a width for the images in CSS, you can use something like this:
/** * Image swatches in product variation buttons. */ .pv-pills .pill label img { width: 3em; }
And that’s it – image swatches for your WooCommerce product variations.
Actions & Filters
Hook | Parameters | Notes |
---|---|---|
pvp_is_active filter | $is_active | Returns true on single product pages if WooCommerce is installed. You can return false from this if you need to disable pill mode for some products. |
pvp_refresh_delay filter | $delay | The delay between the page loading and PV Pills initialising, in milliseconds. Default: 50 |
pvp_heartbeat_interval filter | $interval | PV Pills runs a heartbeat in the browser to check that the pills are not out-of-sync with what WooCommerce thinks is selected. This configures the heartbeat interval in milliseconds. Default: 250 |
pvp_enable_diagnostics filter | $is_enabled | Return true from this filter if you want to see WooCommerce’s original drop-down selectors. This can be useful when trying to understand unexpected behaviour. |
before_enqueue_pvpills_scripts action | Fires immediately before the PV Pills enqueues its scripts and styles. | |
after_enqueue_pvpills_scripts action | Fires immediately after the PV Pills enqueues its scripts and styles. | |
pvpill_label_text filter | $pill_label_text, $term, $attribute_name | The text that’s used for individual pills. By default, $pill_label_text will contain $term->name . This gets sanitised through esc_html so if you want to inject HTML into the pills, you should use pvpill_label_html instead. |
pvpill_label_html filter | $pill_label_html, $term, $attribute_name | The raw HTML that gets inserted inside the pills. By default, this is esc_html($term->name) . |
Changelog: Product Variation Pills
Version 2.3.0
Released: 2023-05-15
- Added a checkbox so you can enable/disable the radio buttons on a per-product basis. By default, radio buttons are enabled.
Version 2.2.5
Released: 2023-01-16
Minor update to the PP Core library.
Version 2.2.4
Released: 2022-10-06
- Added support for translations.
Older releases
Fixed a bug when using custom attributes as variations, when the custom attribute terms had double-quotes in them.
Better handling of when the user clicks the "Clear" button when viewing a product variation.
Added a new feature so you can override the Ajax variations threshold. If you've got products with a large number of variations and you can select invalid product combinations with "Sorry, no products matched your selection. Please choose a different combination.", this new option lets you set a higher threshold... which means you can use a higher number of variation combinations in your variable products.
Added colour pickers to the settings page so you can style the pill buttons without using CSS.
Fixed a bug when certain types of attribute term slugs could cause an element-select query crash.
Update the Power Plugins support library.
Extended the "auto-select singletons" option so it'll try to auto-select pills whenever possible. It makes for a more intuitive user experience when selecting product variations.
Added a new options to control enable auto-select of variations when only one pill is available.
Modified the front-end pill-select logic to play nicer when multiple product attributes are available.
- Minor update and package-rebuild.
- Added some new actions and filters.
- Tidied up the CSS a little.
NEW HOOKS
- do_action( 'before_enqueue_pvpills_scripts' ) fires before the PV Pills scripts/css are enqueued.
- do_action( 'after_enqueue_pvpills_scripts' ) fires before the PV Pills scripts/css are enqueued.
- add_filter( 'pvpill_label_text', $pill_label_text, $term, $attribute_name) lets you override the text inside the pills.
- add_filter( 'pvpill_label_html', $pill_label_html, $term, $attribute_name) lets you override the raw HTML that is rendered inside the pills.
- Integrate with Power Plugins updates.
- Minor code refactoring.
- Added a new function is_pvpills_frontend_required() that can be used to see if PV Pills will be used on the current page.
- Minor update
- Restructured source files. Cleaner.
- Added support for custom product attributes (as variations).
- New logic for the frontend. More robust.
- Easier to override styles at theme-level.
- Detect singleton options (terms) and auto-select them.
- Integration with proper update checking and change log.
- Initial development release.
Georg –
Nice little Plugin! Works really well and is backed by great support. Recommended!
Maxime –
Great plugin, easy to use. And thank you for the great support provided.