1. 部落格
  2. 電子報優化

從零開始建立一個 Email HTML 模板(上)

不論你是前端工程師、後端工程師,還是需要寫 HTML 的設計師,處理 Email HTML 肯定是一件麻煩的事情,帶你一起來面對!

為什麼 Email HTML 這麼難?

就像網頁一樣,製作 Email 必須寫 HTML 與 CSS 製作,但是純手刻製作 Email 看似簡單,實際上門檻更高,因為必須考量到不同的收件端(像是電腦版的 Outlook 就好比瀏覽器屆的 IE 但是更難搞,他是用 Microsoft Word 當作備背後的 render engine…),只能夠寫最古老的 HTML/CSS,寫完還要 inline,但是又要支援 RWD。平常慣用的 variable、display: flex 通通不能用,所以即使你已經是閉著眼睛就能刻畫面的快手,在 Email 這塊還是要乖乖慢下來。

假如是產品的通知信件,因為需要放變數、模版格式要統一,通常會需要手刻,且版型比較單純;如果是行銷信件,就建議使用模版工具製作,編輯大量的圖文、排版比較方便。

在寫文章之前發現 stackoverflow 有針對 Email 寫教學單元,非常的完整,但對初學者來說可能資訊量會有點太大,有需要的人可以參考:https://stackoverflow.design/email/guidelines/getting-started/


以 Component 的邏輯來製作

在開始 coding 前,先用這封 Email 解釋製作邏輯:

一般看到這樣的版型,都會想要左圖這樣切版 padding 包含在 block 裡面。

但是由於 Email 只能用 <table> 的 <td> 建立 padding,在製作多封 Email 的過程中,覺得以下這樣子的 component 規劃是最方便調整與閱讀 code:
Email 切法:每個 component 是一個獨立的 block,該外框決定上下左右的 padding 多少。

有這樣子的概念建立之後,我們就可以開始來寫 code 啦!
本文範例的 HTML 可以在文末找到。

<head>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
   <head>
      <title></title>
      <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
      <meta content="width=device-width, initial-scale=1.0" name="viewport" />
      <meta name="x-apple-disable-message-reformatting" />
      <!--[if !mso]><!-->
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <!--<![endif]--><!--[if gte mso 9]>
      <xml>
         <o:OfficeDocumentSettings>
            <o:AllowPNG/>
            <o:PixelsPerInch>96</o:PixelsPerInch>
         </o:OfficeDocumentSettings>
      </xml>
      <![endif]-->
   </head>
   <body>...</body>
</html>
  • doctype 需要使用 HTML 4.0 的宣告,html 需要加上給 Microsoft office 的 attribute (xmlns:o, xmlns:v)
  • title 留空,信件標題會在發信時設定
  • head 裡會需要加上給 Microsoft office 讀的東西(if !mso, office 等等相關的)

重要基礎:Email HTML 規則

  • 排版只能用 <table>
  • 需要特別針對 outlook 寫 code
  • CSS 要 inline
  • 針對手機版的 style 寫在 <head> 裡,且一定要下 !important
  • 只能使用 CSS2,不能用 CSS3
  • svg 不支援,圖片格式可以使用:jpg, png, gif

Can I Email 以及 Campaign Monitor CSS Support 很好的參考指標,如果忘記哪些不能用,可以去查,但是寫久了你就會知道,反正就是用最簡單的就對了。除非你想要做比較特別的進階效果才會需要去查看支援程度。

<body>

如何寫判斷顯示內容在 Outlook(Outlook conditional HTML)

 <!--[if mso]>
     Outlook content
 <![endif]-->
 <!--[if !mso]><!---->
     Non-outlook content
 <!-- <![endif]-->

延伸做法:

<!--[if !mso]><!---->
不是 Outlook
<!-- <![endif]--><!--[if mso | IE]>
我是 Outlook
<![endif]-->
共用的內容
<!--[if mso | IE]>
我是 outlook
<![endif]--><!--[if !mso]><!---->
不是 Outlook
<!-- <![endif]-->

實際測試發現,Outlook 在 max-width、width 的呈現與其他的都不一樣,所以需要針對 Outlook 與 Non-Outlook 寫外框的 code。根據上述邏輯,會產出這樣的 <body>:

<body class="body cLayout--bgColor" style="background-color:#ffffff; margin:0;width:100%;">
   <table class="layout__wrapper" align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr class="layout__row">
         <td class="layout__column cLayout--bgColor" align="center" width="100%" style="padding-left:10px;padding-right:10px;padding-top:40px;padding-bottom:40px" bgcolor="#ffffff">
            <!--[if !mso]><!---->
            <div style="margin:0 auto;width:100%;max-width:640px;">
               <!-- <![endif]--><!--[if mso | IE]>
               <table role="presentation" border="0" cellspacing="0" cellpadding="0" align="center" width="640" style="margin:0 auto;width:100%;max-width:640px;">
                  <tr>
                     <td>
                        <![endif]-->
                        ...contnet...
                        <!--[if mso | IE]>
                     </td>
                  </tr>
               </table>
               <![endif]--><!--[if !mso]><!---->
            </div>
            <!-- <![endif]-->
         </td>
      </tr>
   </table>
</body>

這樣我們就完成了 body 的基本版型了,設定如下:

  • 背景顏色為:#ffffff
  • 內容居中寬度最寬為 640px(建議 640px-680px,不要超過 800px 是比較舒適的閱讀寬度)
  • body padding: 40px 10px;

註:class 只是方便辨識這一層是什麼,並無任何 style 作用,因為寫到後面一定是超多層 table 有命名會比較清楚。

基本 Component 外框 <table>

<table> 的規則

  • 使用 <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%"> 當你建立一個 table 就必須用 html attributes reset 掉他。
  • 一個 Block 就用一個 table 包起來
  • Block 與 Block 之間的空格用 <td> 的 padding 建立(margin 在 <table> 上不成立)
  • 背景顏色時用 bgcolor="#f7f7f7" 寫在 <td> 上
  • 使用 #aaaaaa 而不要使用 #aaargb(0,0,0)
  • 排版用 <table> 要靠哪裡需要使用 HTML attributes 例如:align="right"valign="middle"

藍色的 Block:

  • 背景為 #f7f7f7f7
  • 左右 padding 32px
  • 下 padding 16px
<table class="block-inner" align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
	<tr>
		 <td class="block-inner__content cBlock--spacingLR " align="left" valign="top" width="100%" bgcolor="#f7f7f7" style="padding-left:32px;padding-right:32px;padding-top:0px;padding-bottom:16px">
				<table width="100%" border="0" cellspacing="0" cellpadding="0">
					 <tr>
							<td align="left" >
							...image content
							</td>
					 </tr>
				</table>
		 </td>
	</tr>
</table>

最外層的 table 是共用的,之後的範例都從最裡面那層 <td> 開始。


標題:Email Text

<td align="left" >
  <h1 style="color:#333333;font-size:18px;font-weight:bold;font-family:'PingFang TC','微軟正黑體','Microsoft JhengHei','Helvetica Neue',Helvetica,Arial,sans-serif;padding:0;margin:0;line-height:1.4">
    おはよう。每一天的早晨。
  </h1>
</td>

不管是 <h1> 還是 <p> 在各個載具呈現都不一樣,所以一定要 inline reset style,文字的 component 很單純,只需要把 reset 寫好就好。如果需要置中文字,用 <td align="center">

連結:Email Link HTML

<td align="left">
  <h1 style="color:#333333;font-size:24px;font-weight:bold;font-family:'PingFang TC','微軟正黑體','Microsoft JhengHei','Helvetica Neue',Helvetica,Arial,sans-serif;padding:0;margin:0;line-height:1.4">
    <a href="https://newsleopard.com/newsleopard/" target="_blank" style="padding:0px;text-decoration:none;display:inline-block">
    <span class="a__text" style="color:#333333;text-decoration:none;font-family:'PingFang TC','微軟正黑體','Microsoft JhengHei','Helvetica Neue',Helvetica,Arial,sans-serif">
      前往電子豹產品
    </span>
  </a>
  </h1>
</td>

連結會由 <a> 裡面包著 <span> 組成,一定要這樣的組合。值得注意的是:span 一定要掛上一個 class name 不然底線的呈現不會在某一個 Outlook 版本 work(不知道為何 @@)

有底線的連結這樣寫:

<a href="https://newsleopard.com/newsleopard/" target="_blank" style="font-size: 16px; color: #333333; text-decoration: underline; display: inline-block; padding: 0">
  <span class="a__text" style="text-decoration: underline; font-family: 'PingFang TC', 微軟正黑體, 'Microsoft JhengHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;">
    read more >>
  </span>
</a>

顏色、大小必須掛在 <a> 上面,字型 reset 寫在 <span>,text-decoraion 兩個都要寫。

圖片:Email Image HTML

width="100%"max-width 在舊版的 Outlook 不成立,一定要寫死 pixel,不然大圖片一定會爆出去。

Responsive Image

以上圖藍色 Block 為例,不論圖片本身大小多少(當然最好不要太大),因為 Block 左右寬度為 32+32,圖片寬度為 640-64=576,寬度要寫在 HTML attribute 上 width="576",另外必須在寬度小於 600px 的螢幕 override 掉他,給他 width="100%"

<td align="center" valign="top" width="100%">
    <img class="img_block" border="0" width="576" src="image-900.jpg" style="display:block;max-width:576px" />
</td>

上面有提到,要寫 responsive style 要把 CSS 放在 <head> 裡的 <style> 裡,並且用 !important

@media only screen and (max-width: 600px) {
.img_block {
    width: 100% !important;
}
}

Image with link

有連結的 img,<a> 的 reset 要寫好:

<td align="center" valign="top" width="100%">
  <a href="https://newsleopard.com/" target="_blank" style="padding:0px;text-decoration:none;display:inline-block">
    <img border="0" width="90" src="logo-300.jpg" alt="newsleopard" style="display:block;max-width:90px" />
  </a>
</td>

如何在 Email 呈現 retina image

因為不支援 svg,想要 icon 或是 logo 呈現清楚不模糊,就用 <img src="icon-80x80.png width="40" border="0" />

按鈕:Email Button HTML

按鈕會比較複雜一點,而 Outlook 也不支援 border-radius,下面以背景顏色為 #005da0,文字 #ffffff 的按鈕為例,以 padding 控制按鈕的大小。注意:padding 與 background-color 要修改的話,非 Outlook 與 Outlook 版本都要記得改到。

<td align="center">
  <table border="0" cellspacing="0" cellpadding="0">
    <tr>
        <!--[if mso | IE]>
        <td align="center" bgcolor="#005da0" style="color:#ffffff;padding-top:7px;padding-bottom:7px;padding-left:60px;padding-right:60px">
           <![endif]--><!--[if !mso]><!---->
        <td align="center" bgcolor="#005da0" style="border-radius:4px">
           <!-- <![endif]-->
           <a class="dnd-button" href="https://newsleopard.com" target="_blank" style="color:#ffffff;border-radius:4px;display:inline-block;text-decoration:none;font-size:16px;font-weight:bold;letter-spacing:1px;padding-top:7px;padding-bottom:7px;padding-left:60px;padding-right:60px">
            <span class="a__text" style="color:#ffffff;text-decoration:none;font-family:'PingFang TC','微軟正黑體','Microsoft JhengHei','Helvetica Neue',Helvetica,Arial,sans-serif">
              逛商品
            </span>
          </a>
        </td>
     </tr>
  </table>
</td>

總結

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <title></title>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <meta content="width=device-width, initial-scale=1.0" name="viewport" />
    <meta name="x-apple-disable-message-reformatting" />
    <!--[if !mso]><!-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!--<![endif]--><!--[if gte mso 9]>
    <xml>
      <o:OfficeDocumentSettings>
        <o:AllowPNG/>
        <o:PixelsPerInch>96</o:PixelsPerInch>
      </o:OfficeDocumentSettings>
    </xml>
    <![endif]-->
    <style> * { text-size-adjust: 100%; -ms-text-size-adjust: 100%; -moz-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } html { height: 100%; width: 100%; } body { height: 100% !important; margin: 0 !important; padding: 0 !important; width: 100% !important; mso-line-height-rule: exactly; } div[style*="margin: 16px 0"] { margin: 0 !important; } table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; } img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; } </style>
    <!--[if gte mso 9]>
    <style type="text/css"> li { text-indent: -1em; } table td { border-collapse: collapse; } </style>
    <![endif]-->
    <style> @media only screen and (max-width:600px) { .cBlock--spacingLR { padding-left: 16px !important; padding-right: 16px !important; } .img_block { width: 100% !important; } } </style>
  </head>
  <body class="body cLayout--bgColor" style="background-color:#ffffff; margin:0;width:100%;">
    <table class="layout__wrapper" align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr class="layout__row">
        <td class="layout__column cLayout--bgColor" align="center" width="100%" style="padding-left:10px;padding-right:10px;padding-top:40px;padding-bottom:40px" bgcolor="#ffffff">
          <!--[if !mso]><!---->
          <div style="margin:0 auto;width:100%;max-width:640px;">
            <!-- <![endif]--><!--[if mso | IE]>
            <table role="presentation" border="0" cellspacing="0" cellpadding="0" align="center" width="640" style="margin:0 auto;width:100%;max-width:640px;">
              <tr>
                <td>
                  <![endif]-->
                  <!-- Block: Start Text -->
                  <table class="block-inner" align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
                    <tr>
                      <td class="block-inner__content cBlock--spacingLR " align="left" valign="top" width="100%" bgcolor="#f7f7f7" style="padding-left:32px;padding-right:32px;padding-top:48px;padding-bottom:16px">
                        <table width="100%" border="0" cellspacing="0" cellpadding="0">
                          <tr>
                            <td align="left" >
                              <h1 style="color:#333333;font-size:18px;font-weight:bold;font-family:'PingFang TC','微軟正黑體','Microsoft JhengHei','Helvetica Neue',Helvetica,Arial,sans-serif;padding:0;margin:0;line-height:1.4">
                                おはよう。每一天的早晨。
                              </h1>
                            </td>
                          </tr>
                        </table>
                      </td>
                    </tr>
                  </table>
                  <!-- Block: End Text -->
                  <!-- Block: Start Image -->
                  <table class="block-inner" align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
                    <tr>
                      <td class="block-inner__content cBlock--spacingLR " align="left" valign="top" width="100%" bgcolor="#f7f7f7" style="padding-left:32px;padding-right:32px;padding-top:0px;padding-bottom:16px">
                        <table width="100%" border="0" cellspacing="0" cellpadding="0">
                          <tr>
                            <td align="center" valign="top" width="100%">
                              <img class="img_block" border="0" width="576" src="https://s3.amazonaws.com/prod-newsleopard-upload-img/40284a7667e982210167e98f2c460000/2020-06-24-07-38-09-1-1.jpg" style="display:block;max-width:576px" />
                            </td>
                          </tr>
                        </table>
                      </td>
                    </tr>
                  </table>
                  <!-- Block: End Image -->
                  <!-- Block: Start Button -->
                  <table class="block-inner" align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
                    <tr>
                      <td class="block-inner__content cBlock--spacingLR " align="left" valign="top" width="100%" bgcolor="#f7f7f7" style="padding-left:32px;padding-right:32px;padding-top:0px;padding-bottom:48px">
                        <table width="100%" border="0" cellspacing="0" cellpadding="0">
                          <tbody>
                            <tr>
                              <td align="center">
                                <table border="0" cellspacing="0" cellpadding="0">
                                  <tbody>
                                    <tr>
                                      <!--[if mso | IE]>
                                      <td align="center" bgcolor="#005da0" style="color:#ffffff;padding-top:7px;padding-bottom:7px;padding-left:60px;padding-right:60px">
                                        <![endif]--><!--[if !mso]><!---->
                                      <td align="center" bgcolor="#005da0" style="border-radius:4px">
                                        <!-- <![endif]--><a class="dnd-button" href="https://www.ulohas.tw/products/8ma26441" target="_blank" style="color:#ffffff;border-radius:4px;display:inline-block;text-decoration:none;font-size:16px;font-weight:bold;letter-spacing:1px;padding-top:7px;padding-bottom:7px;padding-left:60px;padding-right:60px"><span class="a__text" style="color:#ffffff;text-decoration:none;font-family:'PingFang TC','微軟正黑體','Microsoft JhengHei','Helvetica Neue',Helvetica,Arial,sans-serif">逛商品</span></a>
                                      </td>
                                    </tr>
                                  </tbody>
                                </table>
                              </td>
                            </tr>
                          </tbody>
                        </table>
                      </td>
                    </tr>
                  </table>
                  <!-- Block: End Button -->
                  <!--[if mso | IE]>
                </td>
              </tr>
            </table>
            <![endif]--><!--[if !mso]><!---->
          </div>
          <!-- <![endif]-->
        </td>
      </tr>
    </table>
  </body>
</html>

從零開始建立一個 Email HTML 模板(下)… to be continued

有任何問題,歡迎 Email 聯繫我:tin@newsleopard.com