Responsive email column stacking

I have a coded email template with a alternating small/large (image/text) column table cell layout.

 {% if widget_data.section_1.value == 'True' %}
 <!-- Begin ROW 1 Wrapper -->
 <table border="0" cellpadding="0" cellspacing="0" width="100%" id="contentTableOuter" style="{{email_body_border_css}}; background-color:#f9f9f9">
 <tr>
 <td align="center" valign="top">
 <table border="0" cellpadding="0" cellspacing="0" id="contentTableInner">
 <div class="body-container-wrapper">
 <tr>
 <td align="center" valign="top" class="bodyContent" width="100%" colspan="12">

 <table cellpadding="0" cellspacing="0" border="0" width="100%" class="templateColumnWrapper">
 <tr>
 <td valign="top" colspan="5" width="41.66666666666667%" class=" column" style="width:41.66666666666667%; text-align: left; padding: 0; font-family: {{ primary_font }}; font-size: {{ primary_font_size }}; line-height: 1.5em; color: {{ primary_font_color }}; ">
 <div class="widget-span widget-type-linked_image " style="text-align:center" data-widget-type="linked_image">
 <div class="layout-widget-wrapper">
 {% linked_image "feature_image_1" overrideable=true, ending_html='', starting_html='', src='//static.hubspot.com/final/img/content/email-template-images/placeholder_200x200.png', label='Feature Image 1'%}
 </div>
 <!--end layout-widget-wrapper -->
 </div>
 <!--end widget-span -->
 </td>
 <td valign="middle" colspan="7" width="58.333333333333336%" class=" column" style="width:58.333333333333336%; text-align: left; padding: 0; font-family: {{ primary_font }}; font-size: {{ primary_font_size }}; line-height: 1.5em; color: {{ primary_font_color }}; ">
 <div class="widget-span widget-type-rich_text " data-widget-type="rich_text">
 <div class="layout-widget-wrapper">
 {% widget_block rich_text "feature_text_1" overrideable=True, label="Feature Text 1" %}
 {% widget_attribute "html" %}
 <h2>Something Powerful</h2>
 <p>The headline and subheader tells us what you're 
 <a href="#">offering</a>, and the form header closes the deal. Over here you can explain why your offer is so great it's worth filling out a form for.
 </p>
 {% end_widget_attribute %}
 {% end_widget_block %}
 </div>
 <!--end layout-widget-wrapper -->
 </div>
 <!--end widget-span -->
 </td>
 </tr>
 </table>
 </td>
 </tr>
 </div>
 <!--end body wrapper -->
 </table>
 </td>
 </tr>
 </table>
 <!-- End ROW 1 Wrapper -->
 {% endif %}
 {% if widget_data.section_2.value == 'True' %}
 <!-- Begin ROW 2 Wrapper -->
 <table border="0" cellpadding="0" cellspacing="0" width="100%" id="contentTableOuter" style="{{email_body_border_css}}">
 <tr>
 <td align="center" valign="top">
 <table border="0" cellpadding="0" cellspacing="0" id="contentTableInner">
 <div class="body-container-wrapper">
 <tr>
 <td align="center" valign="top" class="bodyContent" width="100%" colspan="12">
 <table cellpadding="0" cellspacing="0" border="0" width="100%" class="templateColumnWrapper">
 <tr>
 <td valign="middle" colspan="7" width="58.333333333333336%" class=" column" style="width:58.333333333333336%; text-align: left; padding: 0; font-family: {{ primary_font }}; font-size: {{ primary_font_size }}; line-height: 1.5em; color: {{ primary_font_color }}; ">
 <div class="widget-span widget-type-rich_text " data-widget-type="rich_text">
 <div class="layout-widget-wrapper">
 {% widget_block rich_text "feature_row_2" overrideable=True, label="Feature Text 2" %}
 {% widget_attribute "html" %}
 <h2>Something Powerful</h2>
 <p>The headline and subheader tells us what you're 
 <a href="#">offering</a>, and the form header closes the deal. Over here you can explain why your offer is so great it's worth filling out a form for.
 </p>
 {% end_widget_attribute %}
 {% end_widget_block %}
 </div>
 <!--end layout-widget-wrapper -->
 </div>
 <!--end widget-span -->
 </td>
 <td valign="top" colspan="5" width="41.66666666666667%" class=" column" style="width:41.66666666666667%; text-align: left; padding: 0; font-family: {{ primary_font }}; font-size: {{ primary_font_size }}; line-height: 1.5em; color: {{ primary_font_color }}; ">
 <div class="widget-span widget-type-linked_image " style="text-align:center" data-widget-type="linked_image">
 <div class="layout-widget-wrapper">
 {% linked_image "feature_image_2" overrideable=true, ending_html='', starting_html='', src='//static.hubspot.com/final/img/content/email-template-images/placeholder_200x200.png', label='Feature Image 2'%}
 </div>
 <!--end layout-widget-wrapper -->
 </div>
 <!--end widget-span -->
 </td>
 </tr>
 </table>
 </td>
 </tr>
 </div>
 <!--end body wrapper -->
 </table>
 </td>
 </tr>
 </table>
 <!-- End ROW 2 Wrapper -->
 {% endif %}

It looks great on desktop email clients, however on mobile the layout breaks.

Is there a way I can set the default layout for all rows so the image is on the left and the text is on the right, but if I set a boolean switch the layout of the image and text elements changes for alternate rows on desktop views.

I can’t think of an elegant solution that doesn’t cause issues with live emails using the template or give content creators issue when building out a email from the template

Thanks

@matttunney,

I had to fight with these same alternating image/text sections in an email template just last week.

I had the same result. They looked great on desktop, but on mobile they would stack causing the order to be like image - text - text - image - image - text - text - image - which, needless to say, didn’t work.

I found a few solutions that involved media queries but of all of the popular email clients, gmail for android doesn’t support media queries! As with most things in life popularity dictates necessity. If media queries don’t work in the most popular clients then media queries do not work.

My solution was finally to just leave the sections in row and alternating. I made the image widths a percentage, like 60%, so they would adjust width without media queries, and I believe I gave the text td’s a width of like 70% and the image td’s 30% so that the text had room to breath on smaller devices.

It’s not the result you want but it works.

Hi @matttunney,

Great news, this can now be configured directly in the drag and drop email editor:

Marketing Email
Mobile Optimised Email
August 16, 2024

What is it?

You can now optimise your marketing emails for mobile, enhancing your end recipient experience, improving engagement rates, and ultimately drive higher conversions.

This rollout provides the ability to hide modules and sections on both mobile and desktop, as well as changing the layout and disable automatic column stacking on mobile.

Why does it matter?

Mobile devices are an increasingly popular way for customers to view email campaigns, meaning it’s now more important than ever to design with mobile devices in mind.

The new Mobile Editor for Marketing Email will enhance the email editing experience that visualises how and where more receipients are opening their emails.

How does it work?

  • To customise which modules or sections appear for desktop or mobile recipients:
  • In your HubSpot account, navigate to Marketing > Marketing Email.
    Click the name of a drafted email, or click Create email in the top right to create a new email.
    Click the desktop desktop icon or mobile mobile icon at the top of the email editor to view and configure the settings for each device type.


*

  • Hover over a module or section and click the hide hide icon to hide that module in the version of the email you’re editing.
    To show all hidden modules for a version you’re editing, click Show all hidden at the top of the email editor.
  • To configure different column layout settings between mobile and desktop devices:
  • Click one of the email sections.
    In the Layout section in the left pane, toggle the All devices switch off, then configure the column layout for Desktop and the stacking layout for mobile.


*

Who gets it?

Marketing Pro, Marketing Enterprise

Learn More:
Join the discussion on our Community
Learn more on the Knowledge Base

The beta can be found here:

If you’re not seeing it yet, you’ll have to be patient for a bit longer or reach out to your customer success manager – but it’s on its way :slightly_smiling_face:

Best regards!