Add WooCommerce Product Overlays

on sale
woocommerce product card with overlay badge
A “New” product

Add WooCommerce product overlays like badges and stickers. Great for New Products, and for advertising featured and sale products. Learn how to use Advanced Custom Fields and a bit of PHP to add some cool refinements to your WooCommerce site.

Add “New”, “Sale” or “Featured” stickers to any of your products.

To follow this tutorial you’ll need to make sure your WordPress site is using a custom child theme. You’ll also need the following plug-ins installed.

We’ll add two overlays in the tutorial, both optional. So you can apply either just one overlay, both of them, or neither of them. WooCommerce already carries an internal flag to mark a product as being “featured”. So we’re going to add a new custom field that lets you add a bit of custom text in the corner, like “New” or “Sale”.

Adding our Custom Field

We’re actually going to add two custom fields for our WooCommerce products:

  • Is the product overlay enabled? (true or false)
  • Product overlay text (string)

In your site’s admin area, go to Custom Fields > Field Groups and click “Add New”. Give the new field group a name, such as “Product Overlay Properties”.

new ACF field group
Our custom field group

Click Add Field to create the first custom field. A lot of options will show up, but it’s not as scary as it looks – we only need to set a couple of key bits of info.

  • Label: Is Product Overlay Enabled?
  • Name: is_product_overlay_enabled (this should be created for you automatically)
  • Type: Choice True / False
  • Stylised UI: Yes (not really required, but makes it nicer to use)

You can leave the other options either blank or at their default values.

Click Add Field again to create a second field and set these properties…

  • Label: Product Overlay Text
  • Name: product_overlay_text
  • Type: Text

That’s it – “text” fields are really easy to add πŸ™‚

Where to Edit our Custom Field Values

Now we’ve defined the custom fields, we need to go to the Location box and tell ACF where we want to show these fields in the back-end. Because these fields are only relevant to products (i.e. they’re not relevant to posts, pages, users or other content), we should set the following:

ACF field group properties
Control the visibility of our custom field group

That’s our field group sorted. Scroll back to the top and click the Publish button to finish things off. Test this now by going to Products > All Products in the admin area, select a product then scroll down and look for the new field group.

To kick things off, pick a product you’re going to use for testing, set “Is Product Overlay Enabled” to “Yes” and put some text into the “Product Overlay Text” field, like “New” – keep the text short.

ACF custom field true/false
Our custom meta box

Set your test product to be a Featured product too – in the Publish box, edit the Catalog Visibility and tick the Featured Product box.

Creating the Product Overlay

To actually add the WooCommerce product overlays, we need to do two things:

  1. Hook WooCommerce to inject some HTML into the product card.
  2. Add a bit of CSS to make it display the new HTML on top of the product image (rather than behind it).

We’re going to hook the action woocommerce_before_shop_loop_item_title to inject our HTML just before the image/title. There are lots of other hooks you can use to inject bits of custom HTML into WooCommerce page elements… but we don’t need any of those for our little module.

Let’s Write some Code

In your custom child theme, create a new file called functions-product-overlays.php and paste the following into it.

<?php

/**
 * FILE: functions-product-overlays.php
 * REF:  https://wp-tutorials.tech/refine-wordpress/add-woocommerce-product-overlays/
 *
 * Add WooCommerce Product Overlays (WPO), text & HTML, to product cards.
 * Add this to your functions.php file:
 *
 *   const WPO_IS_ENABLED = true;
 *   const WPO_IN_CART = false;
 *   require_once 'functions-product-overlays.php';
 */

// Block direct access.
defined('WPINC') || die();

/**
 * Given a product_id, return the overlays as HTML that can be
 * added inside the produc's div container.
 */
function wpo_get_overlays(int $product_id) {
	$html = '';

	// Is this a featured product?
	$terms = wp_get_post_terms(
		$product_id,
		'product_visibility',
		array('fields' => 'names')
	);
	$is_featured = in_array('featured', $terms);

	// Get our custom overlay properties.
	$custom_overlay_text = get_post_meta($product_id, 'product_overlay_text', true);
	$is_custom_overlay_visible = boolval(get_post_meta(
		$product_id,
		'is_product_overlay_enabled',
		true
	));

	// Featured product star.
	if ($is_featured) {
		$html .= '<div class="prod-overlay prod-overlay-feat">';
		$html .= '<i class="fa fa-star" aria-hidden="true"></i>';
		$html .= '</div>'; // .prod-overlay
	}

	// Custom overlay text.
	if ($is_custom_overlay_visible && !empty($custom_overlay_text)) {
		$html .= '<div class="prod-overlay prod-overlay-text">';
		$html .= sprintf(
			'<span class="prod-overlay-label">%s</span>',
			esc_html($custom_overlay_text)
		);
		$html .= '</div>'; // .prod-overlay
	}

	return $html;
}

/**
 * Add the product overlays to products on shop catalogue pages,
 * in the main WP loop.
 * Set WPO_IS_ENABLED=ture to enable this.
 */
function wpo_before_shop_loop_item_title() {
	if (!defined('WPO_IS_ENABLED') || (WPO_IS_ENABLED === false)) {
		// Disabled by configuration.
	} elseif (is_single()) {
		// If we're looking at a single product, don't show the overlay labels.
	} else {
		$product_id = get_the_ID();
		echo wpo_get_overlays($product_id);
	}
}
add_action('woocommerce_before_shop_loop_item_title', 'wpo_before_shop_loop_item_title', 9);

/**
 * Add the overlays to the cart thumbnails.
 * Set WPO_IN_CART=ture to enable this.
 */
function wpo_woocommerce_cart_item_thumbnail($image_html, $cart_item, $cart_item_key) {
	$html = $image_html;

	if (!defined('WPO_IN_CART') || (WPO_IN_CART === false)) {
		// Disabled by configuration.
	} elseif (!array_key_exists('product_id', $cart_item)) {
		// product_id is missing.
	} elseif (empty($product_id = intval($cart_item['product_id']))) {
		// product_id is invalid.
	} else {
		$overlays = wpo_get_overlays($product_id);
		$html = sprintf(
			'<div class="product">%s%s</div>',
			$overlays,
			$image_html
		);
	}

	return $html;

}
add_filter('woocommerce_cart_item_thumbnail', 'wpo_woocommerce_cart_item_thumbnail', 10, 3);

Then include the new code by adding the following to your custom child theme’s functions.php file:

// WooCommerce Product Overlays
const WPO_IS_ENABLED = true;
const WPO_IN_CART = false;

require_once dirname(__FILE__) . '/functions-product-overlays.php';

That’s the core of the project, and you should be able to see it actually working now. Try going to your shop’s main page and you should see your test product has some extra lines stuffed in there before the image/title.

woocommerce product card with overlay badge but no css
Product Overlay

The Star is provided by Font Awesome, using the following HTML:

<i class="fa fa-star" aria-hidden="true"></i>

If you see a funny character here (instead of a star) then you need to add Font Awesome to your site.

Add Some Style

The last stage of this tutorial is to add some styling to our overlays. For this, we just need to add some bits to your custom child theme’s style.css file. The key thing to notice here is that we’ve put the featured product star inside a <div> with the classes “prod-overlay prod-overlay-feat”, and the overlay text uses “prod-overlay prod-overlay-text”. This lets us put common styles into the prod-overlay class definition.

Because these two <div> elements are rendered before the title, if we try to absolute-position the elements they will show up behind the title (obscured by the title), so we need to set the z-index property (positive) to make sure they’re rendered above the title. We’re also going to rely heavily on using absolute position references, so we can put the featured yellow star in the top right of the card, and the overlay text in the top left.

Edit your custom child theme’s style.css file and paste the following into it, to get you started.

/*
* WooCommerce Product Overlays.
*/

.prod-overlay {
	position: absolute;
	z-index: 10;
	text-align: center;
	top: -0.5em;
}

.prod-overlay-feat {
	right: -0.5em;
	width: 1.5em;
	height: 1.5em;
	font-size: 300%;
	color: yellow;
	text-shadow: 0 0 0.0125em black, 0 0 0.0125em black;
}

.prod-overlay-text {
	left: -0.5em;
	width: 3.5em;
	height: 3.5em;
	background-color: rgba( 255, 0, 255, 0.75 );
	border-radius: 50%;
	text-overflow: visible;
	white-space: nowrap;
}

.prod-overlay-label {
	position: absolute;
	left: 50%;
	top: 50%;
	color: white;
	font-size: 200%;
	font-weight: bold;
	transform: translate(-50%,-50%) rotate(-25deg);
	text-shadow: 0 0 0.125em black, 0 0 0.125em black;
}

Save the file and go back to your shop page. Do a forced reload, bypassing the cache so you get the updated style.css file, and check out the difference.

woocommerce product card with overlay badge but no css
Before adding CSS
woocommerce product card with overlay badge and css
After adding CSS

I’ve added a slight grey border to the styled version to check that the overlays overhang the edges nicely. I find this breaks up the product page a bit so it’s not just full of boring rectangles that all look alike. Don’t overhang the edges too much though, or it’ll look stupid on mobile in portrait mode.

infoTry designing for Mobile First. If layout & styles work well on mobile, then they’ll probably also work well on a desktop/laptop. It’s harder to take desktop styles and modify them to work on mobile afterwards.

Wrapping it Up

That should be enough to give you some ideas for your projects.

We’ve kept the PHP code small and purposeful – it does what it’s meant to do, without going over-the-top. This makes it easy to modify when you come back to it in a year’s time. It’s also not too deeply tied-in to your project, so you can drop the PHP and CSS into other WordPress/WooCommerce projects in the future.

The CSS here is enough to get you started, but have a play with it. If you’re not sure what one of the lines does then comment it out, refresh your browser (bypass the cache), and see what changes.

Maybe try creating some additional overlays by adding more custom fields in ACF.

For some ideas on what else you can do with your new WooCommerce product overlays module, have a look at the Active Hands Gripping Aids website.

New product woocommerce overlay badges
The Active Hands Gripping Aids website makes use of similar WooCommerce product overlays

Have fun livening-up your projects by adding lots of shiny custom WooCommerce product overlays! 😎

Like This Tutorial?

Let us know

WordPress plugins for developers

13 thoughts on “Add WooCommerce Product Overlays”

    • It’s a fun way to liven up a WooCommerce catalog page, for sure.

      The Single Product Page is a bit different from the little product cards. You could try hooking the “woocommerce_before_single_product_summary” action, which probably renders the outer/containing div for the single product area – but I’ve not tried it myself. Have a look here to see the actions you can hook into: https://www.businessbloomer.com/woocommerce-visual-hook-guide-single-product-page/

      If you don’t have any joy with that then let me know. I’ll have a rummage through the WooCommerce source code and create a follow-up tutorial, on how to add the same overlays to the Single Product page.

      Paul

      Reply
  1. Hi Paul, thanks for the useful tutorial.

    Is there a way to hook to the cart page? I use an overlay for product and shop, but then it’s missing in the cart image.

    Thanks

    Reply
    • Hi Phil

      I’ve updated the tutorial so you can add the overlays to the cart item thumbnails on the cart page.

      You’ll see I’ve modified the structure a bit. We’ve got a new function called wpo_get_overlays($product_id) that returns the HTML you need for any product. We’ve also got two hook-handlers… One to handle the overlays on shop catalogue pages (woocommerce_before_shop_loop_item_title), and the other to filter the cart item thumbnail HTML (woocommerce_cart_item_thumbnail). This should make it easier to use in your own code, because you can call wpo_get_overlays() from where ever you want.

      I hope this helps

      Reply
  2. Hey, thanks for the plugin tutorial, it gave me an idea for a similar plugin – but this time there’s no need to install ACF and it’s a standalone plugin. It works by hijacking woocommerce product attributes to output an overlay on the product loop and single page main gallery image (just set the attributes to not visible). So, based on your post I created alternative plugin and I’d like to share the code to say thanks. As this is a tutorial site, is there somewhere I can create an account and add a post?

    Reply
    • I’m glad the tutorial was useful. It’s a nice one that I should use more often, myself.

      I don’t host any guest posts on wp-tutorials.tech – all the tutorials are just written and updated by me. I’d be reluctant to open up the site to other tutorial/content creators too, as the domain authority is clean in relation to outbound links.

      Do you not have a personal tech blog site you can post to? I might consider linking back to that (from this tutorial).

      Reply
      • Hi, thanks for your prompt reply! I don’t really post tech tutorials myself, but I have created enough code and plugins that I probably should! I tend to simply use community forums, etc. when I feel I should share code or tips to benefit others. I can give you the code and some small instructions to go with, if you want to publish a blog yourself? I can email you it – you have my email if you want to communicate with me….. would be nice to get a backlink to my company site though – everyone loves a backlink, lol πŸ˜€

        Reply
  3. Great solution, but for some reason it only works in the shopping cart and not in the catalog or on the product pages. Any idea why? Could it be because I’m using Elementor?

    Reply

Leave a comment