Commit d427a0b14fa for woocommerce
commit d427a0b14fa9d7979120e939ff5c96dd2900f436
Author: Tung Du <dinhtungdu@gmail.com>
Date: Thu Oct 15 16:21:08 2026 +0700
Fix duplicate margins on product sale badges (#69835)
* Fix duplicate sale badge margins
* Add changelog entry for sale badge margins
* Fix sale badge test expectation for fluid typography
* chore: keep unreleased sale badge fix out of release notes
Amp-Thread-ID: https://ampcode.com/threads/T-01a13ba5-fcda-75af-9c97-c5aa30c1eec8
Co-authored-by: Amp <amp@ampcode.com>
---------
Co-authored-by: Amp <amp@ampcode.com>
diff --git a/plugins/woocommerce/changelog/fix-sale-badge-margins b/plugins/woocommerce/changelog/fix-sale-badge-margins
new file mode 100644
index 00000000000..63faabed14c
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-sale-badge-margins
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Fix duplicate sale-badge margins in an unreleased change; no release-note entry.
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/sale-badge/block.json b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/sale-badge/block.json
index 56c8ea77112..d7a32671b5d 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/sale-badge/block.json
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/sale-badge/block.json
@@ -40,7 +40,8 @@
"__experimentalSkipSerialization": true
},
"spacing": {
- "margin": true
+ "margin": true,
+ "__experimentalSkipSerialization": true
},
"email": true
},
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductSaleBadge.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductSaleBadge.php
index 5ae476a4131..7b7af2d5ea8 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductSaleBadge.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/ProductSaleBadge.php
@@ -106,6 +106,59 @@ class ProductSaleBadge extends \WP_UnitTestCase {
$this->assert_sale_badge_labels( $markup, $expected );
}
+ /**
+ * @testdox Product Sale Badge applies margins once while preserving its inner badge styles.
+ */
+ public function test_product_sale_badge_applies_margins_once(): void {
+ $product = \WC_Helper_Product::create_simple_product();
+ $product->set_regular_price( '20' );
+ $product->set_sale_price( '15' );
+ $product->save();
+
+ $attributes = array(
+ 'style' => array(
+ 'spacing' => array(
+ 'margin' => array(
+ 'top' => '32px',
+ 'right' => '16px',
+ 'bottom' => '48px',
+ 'left' => '24px',
+ ),
+ ),
+ 'color' => array(
+ 'text' => '#123456',
+ 'background' => '#abcdef',
+ ),
+ 'border' => array(
+ 'color' => '#654321',
+ 'width' => '3px',
+ 'radius' => '8px',
+ ),
+ 'typography' => array(
+ 'fontSize' => '24px',
+ 'lineHeight' => '1.5',
+ ),
+ ),
+ );
+ $markup = do_blocks( '<!-- wp:woocommerce/single-product {"productId":' . $product->get_id() . '} --><div class="wp-block-woocommerce-single-product woocommerce"><!-- wp:woocommerce/product-sale-badge ' . wp_json_encode( $attributes ) . ' /--></div><!-- /wp:woocommerce/single-product -->' );
+ $html = new \WP_HTML_Tag_Processor( $markup );
+
+ $this->assertTrue( $html->next_tag( array( 'class_name' => 'wp-block-woocommerce-product-sale-badge' ) ) );
+ $this->assertStringNotContainsString( 'margin', (string) $html->get_attribute( 'style' ), 'The wrapper must not duplicate the inner badge margins.' );
+ $this->assertTrue( $html->next_tag( array( 'class_name' => 'wc-block-components-product-sale-badge' ) ) );
+ $style = str_replace( ' ', '', (string) $html->get_attribute( 'style' ) );
+
+ foreach ( $attributes['style']['spacing']['margin'] as $side => $value ) {
+ $this->assertStringContainsString( 'margin-' . $side . ':' . $value . ';', $style );
+ }
+ foreach ( array( 'color:#123456;', 'background-color:#abcdef;', 'border-color:#654321;', 'border-width:3px;', 'border-radius:8px;', 'line-height:1.5;' ) as $declaration ) {
+ $this->assertStringContainsString( $declaration, $style, 'Supported styles should remain on the inner badge.' );
+ }
+ // WordPress may resolve the custom font size to a fluid clamp() value.
+ $font_size = (string) wp_get_typography_font_size_value( array( 'size' => $attributes['style']['typography']['fontSize'] ) );
+ $this->assertStringContainsString( 'font-size:' . str_replace( ' ', '', $font_size ) . ';', $style, 'The resolved font size should remain on the inner badge.' );
+ }
+
/**
* Sale badge content options.
*