HTML 文件在PC移动端完美自适应布局的技巧
都2019年了,手機(jī)查看HTML郵件的體驗(yàn)怎么還那么差?
試想一下,你在夜深人靜的時(shí)候,準(zhǔn)備睡前查看一下訂閱的郵件周報(bào),而且還是一個(gè)精心設(shè)計(jì)過的HTML富文本郵件。只不過它只能在pc上完美展現(xiàn),在手機(jī)上最大的字號(hào)只有不到4像素,圖片也變成了馬賽克,會(huì)是一種怎樣的虐心體驗(yàn)。
最近做了一個(gè)群發(fā)郵件的手機(jī)端適配需求就是要解決這個(gè)體驗(yàn)問題,先上效果。
優(yōu)化前:
優(yōu)化后:
當(dāng)然,pc端和網(wǎng)頁版也要完美適配,outlook、foxmail和網(wǎng)頁版效果如下:一、實(shí)現(xiàn)思路
參考比較常見的響應(yīng)式布局,在PC端使用左圖布局,移動(dòng)端右圖。轉(zhuǎn)換時(shí)將圖片的寬度由定寬改為鋪滿,使標(biāo)題等文字換行展示。
1 郵箱渲染html的兼容性問題很多,在桌面和移動(dòng)端渲染電子郵件大約有上百萬種不同的組合方式,所以我們要找出一個(gè)最小子集來書寫html和樣式。然后用平穩(wěn)退化和漸進(jìn)增強(qiáng)的思路,對(duì)其他要適配的設(shè)備和客戶端進(jìn)行保底處理和瀏覽體驗(yàn)優(yōu)化。
2 郵件里不能執(zhí)行腳本,各種郵件客戶端對(duì)media query的支持程度非常有限,所以不可能根據(jù)接收郵件的終端來構(gòu)建不同的dom和cssom,必須擼一套代碼適配所有終端。
3 本次迭代的目標(biāo)是提升手機(jī)端閱讀體驗(yàn),以機(jī)端原生郵箱客戶端和QQ郵箱作為基礎(chǔ)。然后用各種hack手段來適配其他設(shè)備和客戶端。比如用ghost table適配outlook,media query適配網(wǎng)頁版等等。本次的目標(biāo)是針對(duì)公司內(nèi)部用戶的郵件推送優(yōu)化,所以覆蓋的客戶端和操作系統(tǒng)比較有限,如果要覆蓋更多的設(shè)備其實(shí)原理也一樣,見招拆招就好,原則就是在不影響之前已適配的設(shè)備客戶端的情況下對(duì)新設(shè)備做支持。
4 移動(dòng)端web的常規(guī)優(yōu)化對(duì)郵件html同樣適用,比如使用更小的字體、圖片格式選型和壓縮、高精度圖片適配retina屏、用css繪制小圖標(biāo)代替圖片等等。
二、基本原則
1 由于 OutLook從2003版本為了安全開始便使用 Word HTML 引擎進(jìn)行渲染,所以我們只能使用table布局,標(biāo)簽也只能使用table / tr / td / span / img / a,colspan / rowspan也不能放心使用。如果要實(shí)現(xiàn)復(fù)雜布局,就要使用table嵌套。
2 body以外的內(nèi)容全部無效,比如outlook網(wǎng)頁版,它會(huì)把body替換成一個(gè)類名叫x_body的div,然后把body的內(nèi)容全部塞進(jìn)去。
3 style標(biāo)簽的支持程度非常碎片化,media query的支持更加有限,所以要用屬性和style行內(nèi)樣式來保底布局。
4 郵件html里沒有任何腳本。
5 不要簡(jiǎn)寫樣式,比如:padding: 12px 會(huì)在outlook2013失效,改為padding-left/padding-right/padding-top/padding-bottom,font簡(jiǎn)寫也一樣。
6 對(duì)于img標(biāo)簽,用屬性來控制尺寸,style = "width:100px"這樣的代碼在outlook2013會(huì)失效,而且圖片會(huì)把定寬的td和table撐開。width="100%" 這樣的css屬性也是無效的。
7 Outlook 2007-2013 不支持圖片的 margin 與 padding 樣式,必要的時(shí)候可以嘗試 hspace 和 vspace 屬性(非常不建議,用父元素的margin和padding來代替就好了)。
三、實(shí)現(xiàn)過程中各個(gè)終端遇到的問題和解決方法
1 QQ郵箱手機(jī)客戶端(版本信息:IOS11,5.6.2)
QQ郵箱收@qq.com的郵件,會(huì)完全過濾style標(biāo)簽,但是收其他域的郵件會(huì)保留style標(biāo)簽并且不支持media query。所以要適配QQ郵箱有兩個(gè)重點(diǎn)。
第一就是保證行內(nèi)樣式渲染正常。本次最大的一個(gè)功能點(diǎn)就是封面圖手機(jī)端鋪滿,pc端定寬,QQ郵箱又只能支持行內(nèi)樣式,所以封面圖就在style里定義了寬度100%,然后針對(duì)其他設(shè)備和客戶端寫各種hack讓它定寬。
第二是我們要用一些style樣式來調(diào)整pc和網(wǎng)頁上的布局,就要用如下辦法來避免對(duì)手機(jī)QQ郵箱產(chǎn)生副作用。
/*?通過outlook專屬標(biāo)記屬性來避免QQ郵箱手機(jī)版加載?*/ <!--[if?mso]><style?type="text/css"></style> <![endif]--> <!--?通過media屬性來避免QQ郵箱手機(jī)版加載?--> <style?type="text/css"?media="screen?and?(min-width:900px)"></style>2 手機(jī)原生郵件客戶端(版本信息:IOS11,5.6.2)
這個(gè)最省心,支持media query,支持display:flex,在QQ手機(jī)郵箱的基礎(chǔ)上針對(duì)原生客戶端又做了一些體驗(yàn)優(yōu)化。
3 outlook客戶端(版本信息:2007-2016)
這個(gè)最麻煩,就是前面說的Word HTML 引擎。支持style,不支持media query,不支持img樣式。我們這個(gè)需求最大的功能點(diǎn)就是在大于900寬度的屏幕上封面圖按260寬渲染,在小于900寬度下鋪滿屏幕。outlook2013之前又只支持用attr來固定圖片寬高,css定義width完全無效,還會(huì)撐破td和table),一旦寫了固定值就會(huì)影響到上面說的手機(jī)郵箱客戶端,怎么處理這個(gè)沖突就是關(guān)鍵點(diǎn)了。
一開始的想法比較簡(jiǎn)單,直接用style覆蓋attr不就好了嗎?
<img?src="#"?width="260"??>結(jié)果outlook2016出來打臉,在pc上鋪滿屏了。
好,再利用outlook2016支持style的特性,用!important提高優(yōu)先級(jí)覆蓋回來:
<style>img{width:260px!importnat;} </style>記得第一條不?手機(jī)QQ郵箱收內(nèi)部郵件的時(shí)候,支持style不支持media query。這么一來手機(jī)QQ郵箱上又定寬了,被逼進(jìn)絕路。
只好祭出ghost table,把用于其他客戶端的那個(gè)正常的圖片隱藏了,然后顯示一個(gè)專門用于outlook的圖。
<!--[if?mso]> <table?><tr><td> <![endif]--><a?href="#"?class="cover"><img?src="#.jpg"?border="0"?width="100%"></a> <!--[if?mso]></td></tr> </table> <a?href="#"?class="cover"><img?class="img"?src="#.jpg"?border="0"?alt="fsight"?width="260"?height="150"> </a> <![endif]-->同理可以使用這個(gè)outlook專有的標(biāo)記來隱藏所有用于其他客戶端展示的dom元素,針對(duì)outlook做定制,甚至可以暴力一點(diǎn)寫兩套。
這里還遇到一個(gè)問題點(diǎn)就是go在渲染郵件模板的時(shí)候會(huì)自動(dòng)過濾掉所有的注釋,所以需要使用safe標(biāo)記,并且轉(zhuǎn)義寫到一行內(nèi)。
{{safe?"<!--[if?mso]>?<table?align=\"left\"?border=\"0\"?cellpadding=\"0\"?cellspacing=\"0\"?width=\"570\">?<tr>?<td?width=\"570\">?<![endif]-->"?}} code... {{safe?"<!--[if?mso]></td></tr></table><![endif]-->"}}最后就是垂直居中問題,常規(guī)的圖文混排垂直居中方法就是
<div><img?src="#"?><span??>文字</span></div>放到outlook里當(dāng)然無效,td本身的垂直居中在各個(gè)版本中的表現(xiàn)也是各不相同。調(diào)試了半天,居然是給td一個(gè)定高就搞定了。
3 outlook網(wǎng)頁版
有點(diǎn)小坑,它會(huì)把style里面的樣式改寫并且把@media里面的代碼清空。
會(huì)變?yōu)?#xff1a;
所以使用了在style里面寫media屬性的方法來兼容(為了避免手機(jī)QQ郵箱會(huì)加載這段樣式)。
4 QQ郵箱網(wǎng)頁版(https://mail.qq.com)
PC版沒啥好說的,完全支持各種特性,只是移動(dòng)版有點(diǎn)小麻煩:
@media?(min-width:?900px)?{.item{} } @media?(max-width:?900px)?{.item{} }會(huì)被替換為
@media?(min-width:?900px)?{.item{}?//?仔細(xì)看這里,有個(gè)花括號(hào)被吃掉了 @media?(max-width:?900px)?{.item{} }除了最后一個(gè)雙}保留了,其他的"}}"都被替換為"}"。我估計(jì)是正則替換問題,要破也很簡(jiǎn)單,把media寫到style屬性,或者分多個(gè)style標(biāo)簽即可。
另外ipad模式下 QQ郵箱web版會(huì)出現(xiàn)一個(gè)寬度200的側(cè)邊欄。所以郵件正文實(shí)際使用的空間會(huì)少,寫max-width的時(shí)候需要注意(你以為它有768px,實(shí)際上只有568px)。
5 mac原生客戶端和foxmail客戶端 (版本信息:win7.2/mac1.2)
這幾個(gè)客戶端也很好搞,支持media query,支持flex,可以根據(jù)屏幕大小隨意定制樣式。這次只是使用900px作為手機(jī)和pc的分界點(diǎn)。foxmail有個(gè)特性就是邊欄的寬度不算在media query內(nèi),所以當(dāng)左邊欄拉的比較寬的時(shí)候,內(nèi)容會(huì)安裝手機(jī)樣式渲染。
這個(gè)也好解決,在640和900之間多寫幾個(gè)media區(qū)間來適配就好了,體力活。
6 轉(zhuǎn)發(fā)問題
通過上面的工作,系統(tǒng)發(fā)的郵件雖然可以適配了,但是轉(zhuǎn)發(fā)的時(shí)候就還是會(huì)有問題,因?yàn)橛脩艮D(zhuǎn)發(fā)的是經(jīng)過客戶端處理過的郵件,要么是css不全,要么是ghost table沒了。目前來看手機(jī)QQ郵箱客戶端保持的最好,轉(zhuǎn)發(fā)效果基本無損。其他的暫時(shí)無解,所以以防萬一請(qǐng)?jiān)谀愕泥]件里加上鏈接:“如果無法正常瀏覽請(qǐng)點(diǎn)擊”,跳轉(zhuǎn)到網(wǎng)頁讓用戶查看完美的頁面。
四、參考資料
1 郵件樣式支持速查表:
https://www.campaignmonitor.com/css/
2 outlook各版本標(biāo)記:
https://stackoverflow.design/email/base/mso
3 不同郵件服務(wù)商讀取 HTML 郵件已知問題一覽表:
http://app1.studiocloud.com/support/index.php?/article/AA-00861/0/Issues-with-HTML-Emails-in-Different-Email-Clients.html
文章中的鏈接如無法打開,可以點(diǎn)擊下方鏈接跳轉(zhuǎn)到知乎查看,喜歡記得點(diǎn)贊收藏!
歡迎關(guān)注騰訊 WeTest:
總結(jié)
以上是生活随笔為你收集整理的HTML 文件在PC移动端完美自适应布局的技巧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Serverless.com CEO首次
- 下一篇: 轻松 Flutter 入门,秒变大前端