back to blog

Guide to HubSpot's Drag-and-Drop Email Markup

15 min read • February 09, 2024

If you’re building custom modules for HubSpot’s drag-and-drop email builder it can be advantageous to know the classes and styling HubSpot uses for the generated layouts. It will let you target the generated content, but more importantly, allow you to utilize responsive styling already in play.

In a system that currently limits our ability to properly style for cross-client compatibility this can solve for some of the issues you may run into and even cut down on some of your coding time.

Note: HubSpot is currently working on a solution for custom coded drag-and-drop email templates. You can keep an eye on updates in this HubSpot Ideas Forum post.

Classes

There are several classes used throughout HubSpot’s drag-and-drop email that generates inline styling for the main body, sections, and columns.

Body

The following make up the main wrapper of the email:

hse-body-background

Sets the background color (set in Design > Template) around the email.

hse-body-wrapper-table

A wrapper class set on a table to set it to 100% width and height of the parent and remove any email-client set padding and margin.

hse-body-wrapper-td

The class itself doesn’t seem to have any function, but the wrapper has a vertical alignment attribute set to align the content body to the top of the wrapping table.

Sections

The following make up the section wrappers (each row of content in the content body):

hse-section

Adds a 10px left and right padding so that, on mobile, the background color still peeks out around the side of the content body.

hse-section-first

Denotes the first section in the email; adding a 20px top padding to allow the main background color to peek out above the content body.

hse-section-last

Denotes the last section in the email; adding a 20px bottom padding to allow the main background color to peek out below the content body.

hse-column-container

Used for setting the layout settings; including the body width, background color or pattern, and top/bottom padding. By default the background color pulls from the Body color set in Design > Template.

Note: Changing the width of this container and the proceeding columns, across all email-clients, and remaining responsive, would not be possible due to ****drag-and-drop currently not making available the <head> of the email. This is because clients like Gmail strip out any <style> blocks that are not inside the <head>.

Columns

The following classes are used on columns within a section:

hse-column

Turns a <div> into a table-cell on desktop clients and vertically aligns content to the top of the cell.

hs-size-{number}

Sets the size of a column using a 12-grid layout. The following are the available sizes and their equivalent pixel width value:

hse-size-3 150px
hse-size-4 200px
hse-size-5 250px
hse-size-6 300px
hse-size-7 350px
hse-size-8 400px
hse-size-9 450px
hse-size-12 600px

The width is set using both max-width and width set as !important so if you want to set a custom width, forgo adding an hse-size to your hse-column.

hs_padded

Is where the module padding is set and enforces a 20px left and right padding on mobile, making the padding uniform across each column when stacked on top of each other.

hs_cos_wrapper_type_rich_text

This is a class used on the div of the Text module, it’s what applies the font colors and line-heights to text, set in Design > Text styles.

Putting it all together, the hierarchy of classes within a HubSpot generated drag-and-drop email looks like the following:

    
<body>
	<div class="hse-body-background">
		<table class="hse-body-wrapper-table">
			<tbody>
				<tr>
					<td class="hse-body-wrapper-td">
						<div class="hse-section hse-section-first">
							<div class="hse-column-container">
								<div class="hse-column hse-size-3">
									<table>
										<tbody>
											<tr>
												<td class="hs_padded">
													<div class="hs_cos_wrapper_type_rich_text">
														TEXT CONTENT
													</div>
												</td>
											</tr>
										</tbody>
									</table>
								</div>

								<div class="hse-column hse-size-9">
									<table>
										<tbody>
											<tr>
												<td class="hs_padded">
												</td>
											</tr>
										</tbody>
									</table>
								</div>
							</div>
						</div>
						
						<div class="hse-section">
							<div class="hse-column-container">
								<div class="hse-column hse-size-12">
									<table>
										<tbody>
											<tr>
												<td class="hs_padded">
												</td>
											</tr>
										</tbody>
									</table>
								</div>
							</div>
						</div>

						<div class="hse-section hse-section-last">
							<div class="hse-column-container">
								<div class="hse-column hse-size-12">
									<table>
										<tbody>
											<tr>
												<td class="hs_padded">
												</td>
											</tr>
										</tbody>
									</table>
								</div>
								</div>
							</div>
						</div>
					</td>
				</tr>
			</tbody>
		</table>
	</div>
</body>

HTML Element Styling

There are a few specific elements that HubSpot generates reset and font styling for.

Tables

All <table> tags have some table reset styling applied, specifically dealing with borders and table spacing.

    
<table style="border-spacing:0 !important; border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt">

Table Cells

All <td> tags have the Paragraph styling, set in Design > Text styles, applied to them as well as word breaking to avoid text overflowing the cells. Borders are also collapsed and an outlook line-height fix applied.

    
<td style="border-collapse:collapse; mso-line-height-rule:exactly; font-family:Arial, sans-serif; font-size:15px; color:#23496d; word-break:break-word">

Headings, Paragraphs, and Links

  • All text tags (H1, H2, p, a, etc) have an Outlook line-height fix applied
  • <h1> and <h2> have their font-size, set in Design > Text styles, applied
  • <a> tags have their color, set in Design > Text styles, applied
  • Headings 3-6 have predefined font-sizes applied

Important: Colors and line-heights on the paragraph and headings will only be applied if wrapped in an element with the class “hs_cos_wrapper_type_rich_text”.

    
<div class="hs_cos_wrapper_type_rich_text">
  <h1 style="margin:0; mso-line-height-rule:exactly; line-height:175%; font-size:28px; color:#40c9a2">
    Heading 1
  </h1>
  <h2 style="margin:0; mso-line-height-rule:exactly; line-height:175%; font-size:22px; color:#40c9a2">
    Heading 2
  </h2>
  <h3 style="font-size:17px; margin:0; mso-line-height-rule:exactly; line-height:175%">
    Heading 3
  </h3>
  <h4 style="font-size:15px; margin:0; mso-line-height-rule:exactly; line-height:175%">
    Heading 4
  </h4>
  <h5 style="font-size:13px; margin:0; mso-line-height-rule:exactly; line-height:175%">
    Heading 5
  </h5>
  <h6 style="font-size:10px; margin:0; mso-line-height-rule:exactly; line-height:175%">
    Heading 6
  </h6>
  <p style="mso-line-height-rule:exactly; line-height:175%">
    Paragraph
    <a href="https://www.example.com" style="mso-line-height-rule:exactly; color:#00a4bd" data-hs-link-id="0" target="_blank">Link</a>
  </p>
</div>

The markup, with generated inline styles and attributes, will look like this:

    
<body bgcolor="#f5f8fa" style="margin:0 !important; padding:0 !important; font-family:Arial, sans-serif; font-size:15px; color:#23496d; word-break:break-word">
	<div class="hse-body-background" style="background-color:#f5f8fa" bgcolor="#f5f8fa">
	  <table class="hse-body-wrapper-table" style="border-spacing:0 !important; border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; margin:0; padding:0; width:100% !important; min-width:320px !important; height:100% !important" width="100%" height="100%">
		  <tbody>
				<tr>
			    <td class="hse-body-wrapper-td" style="border-collapse:collapse; mso-line-height-rule:exactly; font-family:Arial, sans-serif; font-size:15px; color:#23496d; word-break:break-word">
			     <div class="hse-section hse-section-first" style="padding-left:10px; padding-right:10px; padding-top: 20px;">
			       <div class="hse-column-container" style="min-width:280px; max-width:600px; width:100%; Margin-left:auto; Margin-right:auto; border-collapse:collapse; border-spacing:0">
			         <div class="hse-column hse-size-12">
					   <table>
						 <tbody>
						   <tr>
							 <td class="hs_padded" style="border-collapse:collapse; mso-line-height-rule:exactly; font-family:Arial, sans-serif; font-size:15px; color:#23496d; word-break:break-word; padding:10px 20px">
							   <div class="hs_cos_wrapper_type_rich_text">
								 <h1 style="margin:0; mso-line-height-rule:exactly; line-height:175%; font-size:28px; color:#40c9a2">
								   Heading 1
							     </h1>
							   <h2 style="margin:0; mso-line-height-rule:exactly; line-height:175%; font-size:22px; color:#40c9a2">
							       Heading 2
							   </h2>
							     <p style="mso-line-height-rule:exactly; line-height:175%">
							       Paragraph
								   <a href="https://www.example.com" style="mso-line-height-rule:exactly; color:#00a4bd" data-hs-link-id="0" target="_blank">Link</a>
							     </p>
							   </div>
						     </td>
						   </tr>
					     </tbody>
					   </table>
			         </div>
			       </div>
			      </div>
			    </td>
			  </tr>
			</tbody>
		</table>
	</div>
</body>

You’ll notice that the column itself does not have any inline styles or attributes. The column styling is instead added to the <head> of the email in a <style> block to allow for responsive and client-compatible styling.

Specifically, Outlook.com and Mozilla Thunderbird are set to always show at the specified widths.

All other clients would see the media query that would tell them to only show the specified widths when the window is over 640px wide, otherwise all columns would be shown at 100% width. Below is an example of this styling for the hse-size-5 class:

    
<style>
	.moz-text-html .hse-section .hse-size-5{max-width:250px !important;width:250px !important}
	[owa] .hse-section .hse-size-5{max-width:250px !important;width:250px !important}

	@media only screen and (min-width:640px){
			.hse-section .hse-size-5{max-width:250px !important;width:250px !important}
	}
</style>

Outlook Conditional Comments

Now, there is one piece of these emails that will not dynamically generate for any custom code you add. For sections and columns added to the email through HubSpot’s own features, conditional comments are added to provide markup specifically for Outlook.

When writing custom code, if you create any columns, you would need to add this markup to the code yourself to ensure the columns appear correctly on all versions of Outlook.

    
<div class="hse-section">
    <!--[if !((mso)|(IE))]><!-- -->
      <div class="hse-column-container">
    <!--<![endif]-->
    
    <!--[if (mso)|(IE)]>
      <div class="hse-column-container" style="min-width:280px;max-width:600px;width:100%;Margin-left:auto;Margin-right:auto;border-collapse:collapse;border-spacing:0;">
	      <table align="center" style="border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;width:600px;" cellpadding="0" cellspacing="0" role="presentation">
		      <tr>
    <![endif]-->

			    <!--[if (mso)|(IE)]>
					  <td valign="top" style="width:300px;padding-bottom:20px; padding-top:20px;">
					<![endif]-->
							<!--[if gte mso 9]>
							  <table role="presentation" width="300" cellpadding="0" cellspacing="0" style="border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;width:300px">
							<![endif]-->
								<div class="hse-column hse-size-6">
								  <table role="presentation" cellpadding="0" cellspacing="0" width="100%">
										<tbody>
											<tr>
												<td class="hs_padded">
												</td>
											</tr>
										</tbody>
									</table>
								</div>
							<!--[if gte mso 9]></table><![endif]-->
					<!--[if (mso)|(IE)]></td><![endif]-->

					<!--[if (mso)|(IE)]>
					  <td valign="top" style="width:300px;padding-bottom:20px; padding-top:20px;">
					<![endif]-->
						<!--[if gte mso 9]>
						  <table role="presentation" width="300" cellpadding="0" cellspacing="0" style="border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;width:300px">
						<![endif]-->
							<div class="hse-column hse-size-6">
							  <table role="presentation" cellpadding="0" cellspacing="0" width="100%">
									<tbody>
										<tr>
											<td class="hs_padded">
											</td>
										</tr>
									</tbody>
								</table>
							</div>
						<!--[if gte mso 9]></table><![endif]-->
					<!--[if (mso)|(IE)]></td><![endif]-->

    <!--[if (mso)|(IE)]></tr></table><![endif]-->
    </div>
  </div>

Important: Tags inside of a conditional comment will not have styling or attributes dynamically generated. You will need to add the necessary widths, padding, resets, etc yourself.

While it doesn’t beat having complete control over the template, knowing how the templates work and being able to utilize already set styling in your custom modules can make coding for drag-and-drop a little easier.

 

Discussion