作一封郵件和制作web頁面還是有很大不同的。當不同的瀏覽器都在不斷向標準靠近的同時,大多數郵件客戶端卻止步不前,甚至有一些是在退步的。在2007年,Microsoft 將 Outlook 的渲染引擎從 IE 轉換成 Word的渲染方式,而一些基于web的郵件客戶端,像Gmail和Hotmail,則增加了一些怪異的模式,還有Lotus Notes的一些技巧。
根據我的經驗來看,我們解決這些問題的關鍵是要關注下面三件事情。首先,保持簡單,你的郵件設計的越復雜,你的郵件在某個受歡迎的、不支持標準的客戶端上“抽風”的可能性就越大。其次,你需要將你的編碼技巧退步十年,這通常意味著我們要使用嵌套的表格,將CSS寫成內聯的形式等。最后,你需要對你的設計進行規律性的測試。
因為諸如Gmail和Outlook 2007 無法支持浮動(float)、外邊距(margin)、內填充(padding),你需要使用表格來作為你的郵件的框架。雖然表格嵌套的方法被廣泛支持,但是在對單元格的寬度、外邊距和內填充的處理方法并不一致。為了達到最優的效果,當制作表格結構時,請記住下面的技巧。
1、為每個單元格設置寬度,而不是表格
當你把表格寬度、td 寬度、td的填充和CSS的填充寫到一封郵件時,你看到的結果可能是每個郵件客戶端它們看上去都不一樣。最可靠的方法是我們將為表格的每個單元格(th,td)設置寬度,而不是表格(table)本身。如下:
永遠別指望郵件客戶端能夠計算出你沒有指定寬度的單元格的寬度。它絕對不會。同時也要避免使用基于百分比的寬度,像 Outlook 2007 這樣的客戶端從來不考慮這種寬度方式,特別是這些嵌套的表格。像素級視覺,如果你想對每個單元格做填充,可以使用表單的單元格填屬性或者用CSS的內填充,但是不要這兩種一起使用。
2、嵌套迷思
表格的嵌套相對于設置左右浮動和外邊距(margin)或者表單單元格填充的方法更加穩固。如果你能使用這種表格嵌套的方法達到相同的效果,這將會給你在那些蹩腳的(buggier)郵件終端上面獲得最好的結果。
3、使用一個容器表單來設置 body 背景色彩
很多郵件客戶端會忽略掉在CSS中或者<body>標簽中設置的背景色。針對這種情況,將你的整封郵件用一個寬度為100%的表單包起來,并且為其設置背景色。如下:
你可以使用同樣的方案在背景圖片的設置上,需要記住的是某些郵件客戶端是不支持背景圖片的,這樣你就需要設置一個背景顏色作為備份方案。
4、在單元格中避免使用多余的空格(whitespace)
盡最大可能,避免<td>標簽中出現空格。某些郵件客戶端(Yahoo!或者Hotmail)可能會在某些場景下,對單元格的上面或者下面增加額外的填充,把你的設計破壞掉。
當某些郵件設計師盡他們最大的努力去避免使用CSS時,他們又會去依賴夢魘般的<font>標簽,但實際情況是很多的CSS屬性是被大部分郵件客戶端支持的。請查看下面的跨郵件終端的綜合CSS支持列表list of CSS support,從中你也能發現一些安全的屬性和一些應該被避免使用的屬性。
1、將css寫成內聯(inline)的樣式
Gmail就是這方面的罪魁禍首。CSS被從<head>和<body>中剝離,我們別無選擇的會將樣式寫成內聯的形式。一個好消息是你可以完全自動化的完成轉化。像Premailer提供意見點擊的方式完成這一過程。我強烈建議你將此步驟作為你構建活動的最后一步,你就能感受到這個CSS的所有益處。
2、避免使用字體的簡寫和十六進制計數法
一部分郵箱客戶端會放棄對簡寫的css字體屬性的解析。比如,絕對不要將你的字體樣式設置成下面的樣子。如下:
相反,我們應該寫成下面的形式:
談到字體這個話題,我最近也在不同的郵件客戶端測試引用字體(@font-face)。結果是凄涼的,這些瀏覽器安全的字體在郵件中使用還是遙遙無期。
當我們用CSS來聲明顏色屬性時,有些郵件客戶端并不支持簡寫的16進制的顏色值,比如 color:#f60; 我們需要將其補充完整 color:#ff6600;。為了達到最優的效果,我們需要使用常規寫法。
像前面提到的單元格的間距,段落的間距也無法做到所有客戶端的一致。我看到過設計師使用兩個<br>或者用DIV寫上內聯(inline)的外邊距(margin)樣式彌補這個短板,但是我最近的測試顯示大多數情況下對段落的支持都還是比充足的(有一段時間 Yahoo! 根本不支持段落標簽)。
最好的實踐方法是對每個段落通過內聯(inline)的方法設置外邊距(margin),像下面這樣:
再次提示,在你構建郵件的時候通過在head標簽中增加樣式,然后通過Premailer將他們轉化成每個段落的內聯樣式。
如果你的設計對高度是很敏感的或者需要像素級別的完美,我強烈建議你不要將所有的段落寫到一起,而是將文本的格式化工作放到表單的單元格中來做。你可能會需要使用到表單的嵌套或者單元格填充(cellpadding)/CSS 來達到期望的樣子。下面就是一個例子:
某些郵件客戶端將會用他們的默認樣式覆蓋你的鏈接色,你可以通過兩部來防止其發生。第一,針對每一個鏈接設置一個內聯的(inline)的顏色:
接下來,增加一個冗余的 span 標簽在 a 標簽中。
也許這些方案看上去比較過激,如果這個顏色對你的設計很重要,這個多余的 span 標簽是你達到一致表現的最好解決方案。
很重要的一件需要牢記在心中的關于圖片的事情是你的訂閱者可能看不到你的圖片。如果你有這方面的準備,你就會保持你的內容簡單,并且重要的內容不通過圖片的形式來展示。
在這個思想的指導下,在使用HTML郵件的過程中,下面有一些基本的要領需要牢記:
1、避免占位圖片
雖然使用占位圖片和嵌套表格的方式在10年前很流行,許多郵件客戶端已經將其排除作為一種可靠的技術。很多客戶端會使用一個相同尺寸的空占位來替換圖片,另外一些會將所有的圖片移除。大多數郵件客戶端會給圖片賦予默認的圖片區塊,這將導致訂閱者的第一感覺很差。堅持將單元格賦予固定的寬度,讓其在沒有圖片的時候版式不會亂掉。
2、將圖片定義尺寸
如果你沒有給每個圖片設置尺寸,當圖片沒有被下載時,有些客戶端會自己發明一個他們自己的尺寸,你的版式就亂掉了。同時,確保你的所有圖片在被用到郵件中前,都被賦予了正確的尺寸。某些客戶端會忽略你代碼中設置的尺寸,而去使用真實的圖片尺寸。
3、避免使用 PNG 圖片
Lotus Notes 6 和 7 并不支持 8位(8-bit)和24位(24-bit)的 PNG 圖片,所以需要使用GIF或者JPG格式的圖片,即使這會增加而外的圖片大小。
4、為背景圖片提供備份的顏色
Outlook 2007 不支持背景圖片(aside from this hack to get full page background images working)。如果你想在你的設計中使用背景圖像,提供一個背景色作為備份支持方案。這樣就能同時解決圖片被屏蔽和Outlook 2007的問題。
5、不要忘記標注替代文本(alt text)
缺少標準的支持意味著郵件客戶端對語義化和訪問性良好的HTML郵件的破壞性是很大的。即使這樣,從圖片可能被屏蔽角度看,提供替代文本也是很重要的。這樣即使圖片在默認狀態下被限制,大多數郵件客戶端也能顯示提供的文本來替代。另外還需要技術的是某些客戶端,比如 Outlook 2007, Hotmail 和 Apple Mail 在圖片被屏蔽的時候,并不提供替代文本(alt text).
6、針對 Hotmail 使用顯示hack
令人費解的是,Windows Live Hotmail 對每個圖片增加了幾個像素的填充。一個變通的方案就是使用下面的顯示屬性來解決這個問題。
這樣就能移除掉Hotmail的填充值,但是你也可能會給其它客戶端埋下隱患。
7、避免使用浮動屬性(float)
Outlook 2007 和早期版本的 Notes 并不支持浮動屬性(float)。在郵件中我們可以使用對齊屬性在針對圖像標簽做到浮動圖片的目的。
如果你在 Yahoo!的郵件中發現圖片的怪異表現,增加 align="top" 可能能夠解決你遇到的問題。
由于缺少 Javascript 或者其他對象標簽(object tag)的支持,視頻郵件最大的程度就是gif動畫(如果你認為那是視頻的話)。盡管如此,我最近做的一些關于用html5 videio 標簽的測試結果,還是讓人感覺不錯。
HTML 5的標簽目前在一部分郵件終端是無法運行的,包括 Apple Mail,Entourage 2008, MobileMe 和 iPhone.作為如果視頻不被支持的補救方法,你可以提供穩定的備選內容,比如gif 動畫或者一個可以點擊到瀏覽器播放視頻的圖片。
當然,你是否需要將視頻添加到你的郵件里面,那就是另外一個議題了,如果你的答案是肯定的,你可以使用這些代碼案例。
移動端有機胺的情況近期顯得比較雜亂了,隨著iPhone,Android的發明和Palm和RIM的改進,認為移動端電子郵件終端不重要的年代一去不復返了。
為了給移動端訂閱用戶良好的體現,我們在編碼的過程中也有幾個關鍵點需要牢記心中。
1、保持寬度小于600像素
受限于郵件客戶端的視窗,這條規則來移動視窗到來之前的年代就很重要。事實上,iphone 的視窗是320像素,Droid是480像素,Blackberry大概360像素。堅持最大600像素寬的設計,能夠讓你的郵件縮小到上面提到的設備上面依然可讀。這個尺寸在桌面端和web端的預覽效果也很好。
2、注意文本尺寸的自動調整
作為一個好的特性,基于webkit郵件客戶端(比如 iPhone, Pre 和 Android) 能夠自動調整文本的大小來提高閱讀性。如果你的測試結果表明這項特點給你帶來的好處是破外了你的設計,你可以通過下面的屬性禁用:
雖然近幾年郵件客戶端對標準的支持并沒有取得長足的進步,但是某些郵件客戶端的改變卻從未停止(有好有壞),基于 web 的客戶端,如 Yahoo!、hotmail 和 Gmail 在這方面乏善可陳。我看到過無數次可行的設計方案被停止支持,沒有任何解釋。
基于這個原因,你也要對你的郵件設計保持規律的測試。我發現每個月進行一些快速的測試的小技巧,特別基于web的客戶端。好的消息是經過幾次設計和測試,你將會從這些雜亂無章中找到規律。一些潛在的陷阱將變的可以預計,一個對郵箱友好的設計模型也會在你心中成型。
本文參考“新浪UED”:創建堅如磐石的HTML郵件
們常常會遇到需要通過腳本添加監控的情況,一般我們會選擇使用郵件的方式通知相關人員。
一個簡單的郵件我們可以輕松構建出來(可以參考我之前的文章《Python3使用smtplib發送郵件》),但是有些時候在郵件中增加一個圖片往往能起到事半功倍的效果,畢竟一圖勝千言嘛。
今天我們就看下如何在郵件中添加圖片信息。
# -*- coding: utf8 -*- from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage import smtplib import matplotlib.pyplot as plt if __name__ == '__main__': # 以html格式構建郵件內容 send_str = '<html><body>' send_str += '<center>下邊是一張圖片</center>' # html中以<img>標簽添加圖片,align和width可以調整對齊方式及圖片的寬度 send_str += '<img src="cid:image1" alt="image1" align="center" width=100% >' send_str += '<center>上邊是一張圖片</center>' send_str += '</body></html>' # 畫圖并保存到本地 pic_path = 'test.png' plt.plot([1,3,2,4], '--r') plt.title('這是一個測試') plt.savefig(pic_path) # 構建message msg = MIMEMultipart() # 添加郵件內容 content = MIMEText(send_str, _subtype='html', _charset='utf8') msg.attach(content) # 構建并添加圖像對象 img1 = MIMEImage(open(pic_path, 'rb').read(), _subtype='octet-stream') img1.add_header('Content-ID', 'image1') msg.attach(img1) # 郵件主題 msg['Subject'] = '這是一封帶圖郵件' # 郵件收、發件人 user = "751718003@qq.com" to_list = ["751718003@qq.com", "qixizhuang@yeah.net"] msg['To'] = ';'.join(to_list) msg['From'] = user # 構建并添加附件對象 # 如果不想直接在郵件中展示圖片,可以以附件形式添加 img = MIMEImage(open(pic_path, 'rb').read(), _subtype='octet-stream') img.add_header('Content-Disposition', 'attachment', filename=pic_path) msg.attach(img) # 密碼(有些郵件服務商在三方登錄時需要使用授權碼而非密碼,比如網易和QQ郵箱) passwd = "你的授權碼" # 登錄郵箱 server = smtplib.SMTP_SSL("smtp.qq.com",port=465) server.login(user, passwd) print('Login Successful!') # 發送郵件 server.sendmail(user, to_list, msg.as_string()) print('Send Successful')
看,圖片對象、附件對象、兩個收件人,都按照我們的預期實現了!
單屬性匯總:
1 name屬性
服務器會識別不同的name屬性,并根據name屬性來捕獲不同元素內的數據。
2 value屬性
value 屬性為 input 元素設定值。
對于不同的輸入類型,value 屬性的用法也不同:
type="button", "reset", "submit" - 定義按鈕上的顯示的文本
type="text", "password", "hidden" - 定義輸入字段的初始值
type="checkbox", "radio", "image" - 定義與輸入相關聯的值
注釋:<input type="checkbox"> 和 <input type="radio"> 中必須設置 value 屬性。
注釋:value 屬性無法與 <input type="file"> 一同使用。
注意:單選框和復選框傳遞數據到數據庫時一定要設置value, 否則插入數據失敗;
3 type屬性
它決定了<input>標簽在頁面中的表現樣式和功能
text 文本框
password 密碼框
radio 單選框
checkbox 復選框
file 文件域
hidden 隱藏域
image 圖像域
submit 提交按鈕
reset 重置按鈕
button 普通按鈕
4 size屬性
列表框中size屬性用來設置列表框顯示的行數;
文本框和密碼框會使用size屬性設置域的顯示寬度;
5 disabled屬性
定義disabled屬性可以禁止使用該元素;
無法將數據提交到服務器處理;
6 readonly屬性
常用在輸入性表單對象中(如文本框、密碼框、文本區域),用來禁止輸入任何信息;
可以將數據提交到服務器處理;
7 checked屬性
它與disabled屬性一樣沒有屬性值,常用在選擇性表單對象中,定義對象處于被選中狀態(如單選按鈕和復選框)
但在列表框或者下拉式菜單中,為了表示被選中的項目,可使用selected屬性;
7 placeholder屬性
規定幫助用戶填寫輸入字段的提示。
表單對象:
1 文本框
<input type="text" name="textfield" id="textfield" value="單行文本框" size="20" maxlength="20">
必需的屬性:name type
2 密碼域
<input type="password" name="passwordfield" id="passwordfield">
必需的屬性:name type
3 文本域
<textarea name="textarea" cols="20" rows="5" wrap="physical"></textarea>
必需的屬性:name cols rows
wrap屬性 默認值:輸入的文本會自動換行。當數據提交到服務器被處理時, 換行符不會隨輸入的文本一同被提交到服務器;
off(也可寫成wrap):不自動換行, 當輸入的內容超出文本區域右邊界時, 文本將向左滾動, 并顯示滾動條。
如果希望換行,必須手動輸入回車鍵才能將插入點移到下一行;
virtual:文本能夠自動換行, 當數據提交到服務器被處理時, 換行符不會隨輸入文本一同提交到服務器;(默認值)
physical:文本能夠自動換行, 當數據提交到服務器被處理時, 換行符將會隨輸入的文本一同被提交到服務器進行處理;
關于如何限制文本域輸入字符串的長度 見javascript|語法|設置文本框
HTML5中wrap中屬性值修改為hard|soft
soft 當在表單中提交時, textarea 中的文本不換行, 默認值。
hard 當在表單中提交時, textarea 中的文本換行(包含換行符)。
當使用 "hard" 時, 必須規定 cols 屬性
4 單選按鈕
單選按鈕傳遞的信息簡單,如1或0、True或False。
<input type="radio" name="radio" value="1"/>選項1
<input type="radio" name="radio" value="2"/>選項2
<input type="radio" name="radio" value="3"/>選項3
多個單選按鈕通過定義相同的name屬性, 以實現捆綁在一起;
必需的屬性:type name value
5 復選框
<input type="checkbox" name="checkbox[]" value="1"/>選項2
<input type="checkbox" name="checkbox[]" value="2"/>選項2
<input type="checkbox" name="checkbox[]" value="3"/>選項2
通過設置相同的name屬性可以把多個復選框捆綁在一起;
必需的屬性:type name value
6 列表框/下拉菜單
<select name="select" size=1>
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
</select>
如果select元素中不設置size屬性,則該元素會顯示為下拉菜單樣式
<select name="select" size="1" multiple="multiple">
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
</select>
如果希望以列表框形式顯示,則可以使用size屬性指定列表框的高度(顯示幾個選項);
還可以通過mutiple屬性定義列表框是否為多選(默認是單選);
通過<optgroup>標簽把相關的選項組合在一起:
<select>
<optgroup label="PHP版塊">
<option value ="resource">資源共享</option>
<option value ="study">學習交流</option>
<option value ="salary">薪酬待遇</option>
</optgroup>
<optgroup label="IOS版塊">
<option value ="resource">資源共享</option>
<option value ="study">學習交流</option>
<option value ="salary">薪酬待遇</option>
</optgroup>
</select>
注意:其中PHP版塊和IOS版塊不能被選中
所有主流瀏覽器都支持 <optgroup> 標簽。
7 文件域
<input type="file" name="file"/>
<input type="file" name="file" multiple/>
8 按鈕
提交按鈕
<input type="submit" name="" value="提交"/>
name值必須給出
重置按鈕
<input type="reset" name="" value="重置"/>
普通按鈕
<input type="button" name="" value="普通按鈕"/>
它一般是配合javascript來使用;
關于控制表單提交按鈕見: javascript|語法|控制表單提交
9 圖像域
<input type="image" name="image" value="提交" src="images/vote_d.gif" alt="提交" align="middle"/>
10 隱藏域
限制上傳文件大小
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
傳遞ID值
<input type="hidden" name="id" value="<?php echo $result['id'];?>" />
11 button標簽
在 button 元素內部,您可以放置內容,比如文本或圖像。這是該元素與使用 input 元素創建的按鈕之間的不同之處。
<button type="button" name="button" value="按鈕"><img src="hw001.jpeg"/></button>
普通按鈕<button type="button">普通按鈕</button> 它一般是配合javascript來使用, 默認值
提交按鈕<button type="submit">提交按鈕</button>
重置按鈕<button type="reset">重置按鈕</button>
提交表單
enctype屬性
該屬性包含兩種方式:
application/x-www-form-urlencoded 是默認編碼類型
multipart/form-data
multipart/form-data編碼方式可以用來傳輸二進制數據或者非ASCII字符的文本(如圖片、不同格式的文件等),上傳文件必須使用此屬性
multipart: 多部件的
multiple: 多重的
text/plain
text/plain將表單屬性發送到電子郵箱時,enctype的值必須設為"text/plain",否則將會出現亂碼。
發送電子郵件的表單程序
<form name="form1" method="post" action="mailto:marker@broadview.com.cn" enctype="text/plain">
</form>
action 表單提交的腳本
如果傳遞到本頁面,則直接輸入控制 action=""
表單提交方式method:post/get
<form action="test.php?id=5" method="post" >
name: <input type="text" name="name" value="100">
</form>
id=5是get傳, name="100" 是post傳! //高洛峰解釋
action="" 表示傳遞到當前腳本文件
target 指定提交到哪一個窗口
_blank 打開新窗口
_self 當前的窗口,默認值
_parent 上一層窗口
_top 最上層窗口
框架名稱 指定指定窗口或框架名稱
label標簽
作用: 擴大觸控區域, 為了提升用戶體驗, 點擊文字也能選中表單
<form action=" method="get" accept-charset="utf-8">
<label>電子郵箱: <input type="text" name="email" value="" placeholder="請輸入電子郵箱"/></label><br/>
<label>密碼: <input type="password" name="password"/></label><br/>
<label for="address">地址</label>
<input type="text" name="address" id="address" placeholder="請輸入地址" />
</form>
for與id一致
<input type="radio" id="sec" name="sex"> <label for="sex">男</label>
簡化寫法:
<label><input type="checkbox"/>周杰倫-晴天</label>
注意: "for" 屬性可把 label 綁定到另外一個元素。請把"for"屬性的值設置為相關元素的 id 屬性的值。
PHP實例:創建發送郵件信息的html表單
代碼:
<html>
<head>
<title>簡單郵件發送表單</title>
</head>
<body>
<h1>Mail Form</h1>
<form name="form1" method="post" action="simpleEmail.php">
<table>
<tr><td><b>To</b></td><td><input type="text" name="mailto" size="35"></td></tr>
<tr><td><b>郵件主題:</b></td>
<td><input type="text" name="mailsubject" size="35"></td></tr>
<tr><td><b>郵件內容</b></td>
<td><textarea name="mailbody" cols="50" rows="7"></textarea></td>
</tr>
<tr><td colspan="2">
<input type="submit" name="Submit" value="發送">
</td>
</tr>
</table>
</form>
</body>
</html>
simpleEmail.php
*請認真填寫需求信息,我們會在24小時內與您取得聯系。