Product badges show through the sticky header on mobile
Symptoms
After we restyled the SALE badges and Wishlist hearts on product photos, the store owner sent a screenshot from their phone. When scrolling, the badge and the heart slid over the sticky header with the menu instead of disappearing under it.
Environment
WordPress with WooCommerce and a page builder. The header is sticky (position: sticky). The badges are absolutely positioned in the corner of the photo and have a z-index so they sit above the image.
Diagnosis
- It didn't show on desktop. On mobile the header is shorter and more product cards scroll underneath it.
- In DevTools: the header itself had a high
z-index, but it was wrapped in a page builder container withz-index: 1, which created its own stacking context. From the outside, the whole header behaved as layer 1. - The badges had a
z-indexhigher than 1 and weren't in a stacking context of their own. So they competed directly with the header's wrapper, and won.
Cause
z-index is only compared within the same stacking context. A high number inside a wrapper with z-index: 1 doesn't help against an element outside it with 2 or more.
Risks if left untreated
On mobile, where most customers shop today, the site looks broken: badges slide over the menu and cover it. A small flaw, but it erodes trust in the shop and can block navigation. An amateur fix that just raises z-index numbers only moves the problem elsewhere.
Fix
Instead of raising the header's numbers (and fighting the page builder), we put the badges in a stacking context of their own:
.woocommerce ul.products li.product,
.single-product .elementor-widget-container:has(> span.onsale),
.single-product .woocommerce-product-gallery {
isolation: isolate !important;
}
isolation: isolate turns the product card and the product page photo into a separate layer. The badge stays above the photo inside the card, but the card as a whole behaves like regular content relative to the header. The CSS lives in a separate mu-plugin, so reverting means deleting one file.
Verification
After purging the cache, we went through the shop, a category and a product page with its Related products section on both mobile and desktop. The badges and the heart sit above the photo and slide under the header when scrolling.
Prevention and lessons
When you give an element a z-index, wrap its parent with isolation: isolate. The number then only applies inside it and never collides with a sticky header or a popup. Test scrolling on mobile, not just a static screenshot.
Related services: Crashes and errors Online store and checkout