Commit c043b2aab3e for woocommerce
commit c043b2aab3e851e9998330dba014064ad2e58f43
Author: Allison Levine <1689238+allilevine@users.noreply.github.com>
Date: Tue Sep 8 09:07:23 2026 -0400
fix(email-editor): stop Media & Text floating so buttons don't bleed over it (#68443)
* fix(email-editor): stop Media & Text floating so buttons don't bleed over it
The Media & Text wrapper table emitted align="left" (from the default text
align), which email clients render as float:left. That pulled the block out of
normal flow, so the block after it failed to clear it — a following buttons
block overlapped it and painted its background across the media and text above.
Drop the align attribute; horizontal alignment is already carried by the
text-align declaration in the wrapper's inline styles, so alignment is preserved
while the block stays in normal flow. This is the same fix #66833 applied to the
gallery wrapper for the same reason.
Verified by rendering a media-text block followed by a center-justified buttons
block through the real renderer and loading the output in WebKit at 390px: the
button background covers the whole media & text block before the change and sits
cleanly below it after.
Adds a regression test asserting the wrapper table carries no float-triggering
align attribute while retaining text-align.
Fixes CM-520.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv2sgScyH9Ahv2rd65EuJu
* test(email-editor): pin RTL wrapper alignment to the wrapper tag, not a substring
Both the media-text and gallery RTL tests asserted alignment with a bare
assertStringContainsString( 'align="right"', $rendered ) over the whole render.
That does not pin the wrapper: the Outlook-only spacer table emitted by
Abstract_Block_Renderer::add_spacer() carries align="right" inside an
<!--[if mso | IE]--> conditional comment, so the assertion keeps passing after
the wrapper's own attribute is removed.
The gallery test has therefore been passing for the wrong reason since #66833
removed that attribute, and the media-text test would have started doing the
same with this branch's fix — in both cases silently dropping the RTL coverage
the test names claim.
Assert against the wrapper tag itself instead, via WP_HTML_Tag_Processor: no
align attribute, and text-align:right in its inline style. Verified both
assertions fail ("Failed asserting that 'right' is null.") when the attribute
is reinstated on either renderer.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv2sgScyH9Ahv2rd65EuJu
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
diff --git a/packages/php/email-editor/changelog/fix-cm-520-media-text-float-button-bleed b/packages/php/email-editor/changelog/fix-cm-520-media-text-float-button-bleed
new file mode 100644
index 00000000000..187303c87e4
--- /dev/null
+++ b/packages/php/email-editor/changelog/fix-cm-520-media-text-float-button-bleed
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Keep Media & Text blocks in normal document flow so a button placed after one no longer paints its background across it. The wrapper table's align="left" rendered as a float in email clients, pulling the block out of flow so the following block failed to clear it. Alignment is preserved via the existing text-align CSS.
diff --git a/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-media-text.php b/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-media-text.php
index 818d341db3f..1246018f7d9 100644
--- a/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-media-text.php
+++ b/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-media-text.php
@@ -101,10 +101,16 @@ class Media_Text extends Abstract_Block_Renderer {
);
// Apply class and style attributes to the wrapper table.
+ //
+ // Intentionally omit the `align` attribute. `align="left"` (or "right") on a table renders as
+ // `float: left` in email clients, taking the block out of normal flow — the block that follows
+ // then fails to clear it and overlaps it, so a following button paints its background across
+ // the media & text block above. Horizontal alignment is already carried by the `text-align`
+ // declaration in $block_styles['css'], so dropping the attribute preserves alignment while
+ // keeping the block in normal flow. Same fix as the gallery wrapper.
$table_attrs = array(
'class' => 'email-block-media-text ' . $original_wrapper_classname,
'style' => $block_styles['css'],
- 'align' => $rendering_context->get_default_text_align(),
'width' => '100%',
);
diff --git a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Core_Renderers_Rtl_Test.php b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Core_Renderers_Rtl_Test.php
index d373e0f218a..5c966e35636 100644
--- a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Core_Renderers_Rtl_Test.php
+++ b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Core_Renderers_Rtl_Test.php
@@ -110,8 +110,7 @@ class Core_Renderers_Rtl_Test extends \Email_Editor_Integration_Test_Case {
$this->assertNotFalse( $media_position );
$this->assertNotFalse( $text_position );
$this->assertLessThan( $text_position, $media_position );
- $this->assertStringContainsString( 'text-align:right;', $rendered );
- $this->assertStringContainsString( 'align="right"', $rendered );
+ $this->assertWrapperIsRtlAlignedWithoutFloat( $rendered, 'email-block-media-text' );
}
/**
@@ -202,8 +201,7 @@ class Core_Renderers_Rtl_Test extends \Email_Editor_Integration_Test_Case {
$this->rtl_context
);
- $this->assertStringContainsString( 'text-align:right;', $rendered );
- $this->assertStringContainsString( 'align="right"', $rendered );
+ $this->assertWrapperIsRtlAlignedWithoutFloat( $rendered, 'email-block-gallery' );
}
/**
@@ -225,6 +223,40 @@ class Core_Renderers_Rtl_Test extends \Email_Editor_Integration_Test_Case {
$this->assertOuterSpacerAligned( $rendered, 'right' );
}
+ /**
+ * Assert that a block's wrapper table carries its RTL alignment as a `text-align` declaration
+ * rather than as an `align` attribute.
+ *
+ * `align="right"` on a table renders as `float: right` in email clients, taking the block out of
+ * normal flow so the block that follows fails to clear it. Searching the whole render for the
+ * substring `align="right"` does not pin this down: the Outlook-only spacer table emitted by
+ * Abstract_Block_Renderer::add_spacer() carries one inside a conditional comment, so such an
+ * assertion keeps passing after the wrapper's own attribute is gone. Inspect the wrapper tag.
+ *
+ * @param string $rendered Rendered HTML.
+ * @param string $wrapper_class Class identifying the block's wrapper table.
+ */
+ private function assertWrapperIsRtlAlignedWithoutFloat( string $rendered, string $wrapper_class ): void {
+ $processor = new \WP_HTML_Tag_Processor( $rendered );
+ $this->assertTrue(
+ $processor->next_tag(
+ array(
+ 'tag_name' => 'table',
+ 'class_name' => $wrapper_class,
+ )
+ ),
+ sprintf( 'Expected a wrapper table with the %s class.', $wrapper_class )
+ );
+
+ // No float-triggering align attribute ( get_attribute() is null when the attribute is absent ).
+ $this->assertNull( $processor->get_attribute( 'align' ) );
+
+ // RTL alignment is carried by the text-align declaration instead, keeping the block in flow.
+ $style = $processor->get_attribute( 'style' );
+ $this->assertIsString( $style );
+ $this->assertStringContainsString( 'text-align:right;', $style );
+ }
+
/**
* Assert that the outer spacer wrapper uses the expected alignment.
*
diff --git a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Media_Text_Test.php b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Media_Text_Test.php
index a1efd617a41..9e7c883f69b 100644
--- a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Media_Text_Test.php
+++ b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Media_Text_Test.php
@@ -76,6 +76,38 @@ class Media_Text_Test extends \Email_Editor_Integration_Test_Case {
$this->assertStringContainsString( 'Media content', $rendered );
}
+ /**
+ * The media & text wrapper table must not carry an `align="left"`/`align="right"` attribute: those
+ * render as `float` in email clients, pulling the block out of normal flow so the block that follows
+ * fails to clear it. A button placed after it then paints its background across the media & text
+ * block above. Horizontal alignment must instead come from the `text-align` CSS declaration, which
+ * keeps the block in normal flow.
+ */
+ public function testItDoesNotFloatWrapperTableWithAlignAttribute(): void {
+ $rendered = $this->media_renderer->render( '', $this->parsed_media, $this->rendering_context );
+
+ // Locate the wrapper table by its class. Parsing the tag with WP_HTML_Tag_Processor is more
+ // robust than matching the raw HTML string, and matches the convention used elsewhere here.
+ $processor = new \WP_HTML_Tag_Processor( $rendered );
+ $this->assertTrue(
+ $processor->next_tag(
+ array(
+ 'tag_name' => 'table',
+ 'class_name' => 'email-block-media-text',
+ )
+ ),
+ 'Expected a media & text wrapper table with the email-block-media-text class.'
+ );
+
+ // No float-triggering align attribute on the wrapper table ( get_attribute() is null when absent ).
+ $this->assertNull( $processor->get_attribute( 'align' ) );
+
+ // Alignment is preserved via the text-align CSS declaration instead, keeping the block in normal flow.
+ $style = $processor->get_attribute( 'style' );
+ $this->assertIsString( $style );
+ $this->assertStringContainsString( 'text-align', $style );
+ }
+
/**
* Test it handles media positioning
*/