CSS通用架構:打造自己的Reset.css
最後更新:2017-02-28
來源:互聯網
上載者:User
0,引言
每每有新項目,第一步就是應當使用一個reset.css來重設樣式。濫用不如不用,直接拿個現成的reset.css過來將導致後期各種離奇bug的發生。所以最好還是自己寫一個reset.css,並且要明白每一條reset都是用來做什麼的。reset.css本意就是重設樣式,我始終建議把.clearfix放入layout.css,而把h1、h2之類的定義放進typography.css。 具體如何規劃網站CSS結構,不在文本討論之列,可以參考Smashing Magazine上的文章,國內有差強人意的中文譯版。注意,本文把reset分成了兩個部分,一個是純reset.css,可以用於任何項目。另一個是用於特定項目的“reset”,自訂修改的內容,這些內容可以放在layout.css、typography.css之類的檔案中,他們共同匯入到一個base.css形成一個項目的基礎樣式。本文就是來介紹如何寫一個合適所有項目的通用的reset.css,以及介紹在設定玩reset.css之後需要針對不同項目要首先要設定的內容。
1,基礎
牛頓是站在巨人伽利略的肩膀上的,我們也可以這麼做。首先我們要選定一個前進的基礎。
請永遠不要使用
複製內容到剪貼簿
代碼:
* { margin: 0; padding: 0; }
這問題太多了,在此不多加表述。
目前比較流行的有Eric Meyer的重設樣式和YUI的重設樣式。另有Condensed Meyer Reset簡化Eric Meyer的樣式。有趣的是,Eric的重設樣式也是源於YUI的。而那份簡化版又把Eric的樣式簡化回YUI的樣式了 。但同時,糟糕的是,網上流傳的比較廣的(尤其是國內)都不是最新的版本。上面兩個頁面裡直接看到的都不是最新的,Eric專門為有一個reset.css頁面。而YUI目前的版本(2.7.0)的reset.css實際地址裡,比上面的頁面中還多一些東西。此外,我們還可以基於一些常見的架構,比較著名的比如Blueprint或者Elements CSS Framework(這個的reset也是源自於Eric Meyer的)。OK,準備工作就差不多了。以上這些都可以作為參考資料來組織我們自己的reset。我這裡主要採用YUI,兼帶Eric的reset。
2,預設色彩
對於頁面是不是有預設背景色和前景色彩,YUI和Eric有著不同的看法。
YUI重設背景色為白色而文字顏色為黑色。
複製內容到剪貼簿
代碼:
html { color: #000; background: #FFF; }
而Eric在當前最新版中讓所有顏色為透明,他認為透明才是最原始的顏色。雖然他曾一度認為也應當設定白色背景色、黑色文字顏色。至於最後為什麼改了,Eric並沒有給出具體理由。
這個問題我基本認為是使用者自訂的更重要還是你的設計更重要的問題。我個人的觀點是,如果你的設計本身就是白色背景,那麼不要設定背景。一小部分中高水平的使用者,他們會自訂網頁預設背景色。設定成他們喜歡的背景色,比如淺藍色。基本常見的瀏覽器都提供了這個簡單的功能。而我們的背景色重設則會破壞使用者的選擇——儘管這樣能保證你的設計原汁原味的呈現給所有使用者。當然我知道,更高端的使用者會用Stylish之類的Firefox擴充來自訂頁面。但不得不說,只會用“選項”來調背景色的使用者更多,不是嗎?而同時,如果設計本身就有其他背景色,比如黑色、藍色、綠色之類的,OK,這些設計當然可以設定背景色。但請不要放進reset.css裡。這裡是重設樣式的地方,不是你設計的地方。請把你的設計放在更廣袤的土地上。
所以,簡單說來,NO,不要在reset中設定背景色。
那麼,文字顏色呢?原則上來說,也是不應該設定文字顏色的。但是IE中的表單元素中legend這個對象比較特別,跟主題結合的比較緊密。legend會預設有自己的顏色(跟當前的主題有關)而不會繼承父元素的顏色(即便設了color:inherit;)。
從某些角度來說,可以想當然地認為設定字型顏色人數遠小於設定背景色的人數;以及認為就算設定了背景色,人們看到legend元素是黑色的也不會覺得奇怪。因此,YUI在其reset中設定了legend {color: #000;}是無可厚非的。
但反過來說,把這個放到typography.css或者form.css裡豈不是更好?不同的頁面設計,其對legend的色彩要求很可能是不同的,放在reset.css裡重複定義是沒有必要的。因此這條CSS規則可以作為在reset.css之後首先應當設定的規則。
3,padding和margin
曾經一度流行的
複製內容到剪貼簿
代碼:
* { margin: 0; padding: 0; }
也就是出於這個目的。讓各個元素的padding和margin都歸零,尤其是那些h1和p以及ul/ol/li之類的元素,還有,body本身也是有margin的。清除元素的padding和margin是很有用的。
YUI這樣做:
複製內容到剪貼簿
代碼:
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td { margin: 0; padding: 0; }
而Eric這樣做:
複製內容到剪貼簿
代碼:
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent; }
可以看到,Eric把幾乎所有的元素都寫上了規則。而YUI只把有padding和margin的元素清空樣式,而其他元素則不動。我個人比較偏好YUI的做法,因為他這樣可以避免給一些無關元素帶上不必要的樣式。導致元素過多時的效能下降。但Eric的也有可取之處,他這樣寫,整個reset.css可以小上不少位元組,對伺服器的壓力會小一些。但進一步想,這種做法跟用 * 來選擇所有元素還有什麼區別呢?這已經幾乎囊括了所有元素了!你怎麼用呢?看你自己喜好了。
4,邊框
YUI裡:
複製內容到剪貼簿
代碼:
fieldset, img { border: 0; } abbr, acronym { border: 0; font-variant: normal; }
Eric已經在上一條中把所有的邊框都清掉了,還是推薦用YUI的,理由同上。
5,外邊框(outline)
這個就是元素擷取焦點時的虛線框,在ie之外的瀏覽器上可以像下面Eric做的那樣,通過設定outline來消除。
複製內容到剪貼簿
代碼:
/* remember to define focus styles! */ :focus { outline: 0; }
而YUI則沒有設定這一條。而在Eric的樣式中,可以看到Eric的提醒:務必重新定義擷取焦點後的樣式!
這點其實很重要,出於可訪問性的角度出發,那些不便於使用滑鼠的人基本上都是用tab導航來瀏覽網頁的。擷取焦點的元素有特定樣式的話可以極大協助這類群體的使用者,通常建議設定成跟:hover一樣。經常設計上會因為這個虛線框而大打折扣。因此這條保留在reset中,並且作為reset.css之後及早定義的規則。
另外,對於在Firefox之類的支援outline的瀏覽其中,除了擷取焦點的元素外,瀏覽器本身並沒有給元素設定outline屬性,所以,像Eric那樣把所有元素的outline設成0,我就覺得沒有太大必要了。
6,字型樣式(font style/weight/size/variant)
YUI裡,分成了多條:
複製內容到剪貼簿
代碼:
address, caption, cite, code, dfn, em, strong, th, var, optgroup { font-style: inherit; font-weight: inherit; } h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; } abbr, acronym { border: 0; font-variant: normal; } input, button, textarea, select, optgroup, option { font-family: inherit; font-size: inherit; font-style: inherit; font-weight: inherit; } /*@purpose To enable resizing for IE */ /*@branch For IE6-Win, IE7-Win */ input, button, textarea, select { *font-size: 100%; }
Eric則在他最終版的reset中去掉了關於這些的樣式重設,只保留了
複製內容到剪貼簿
代碼:
font-size: 100%;
理由見下文。
但通常情況下,我認為還是重設一下這些樣式好,比如strong元素,很多時候只是語義而已,並非希望他真的加粗。可能會有背景色或者其他方式來強調。而之所以這裡都用了inherit這個繼承屬性而不是定義
複製內容到剪貼簿
代碼:
font-weight: normal;
可以在 Eric 先前的reset文章中看到。這是為了防止——父元素字型加粗了,而沒有一個子項目繼承加粗屬性(因為設定了normal)——這種情況的發生。所以把YUI中設定h1-h6的樣式以及abbr和acronym的兩句樣式都改成inherit會比較好。
此外,對於h1-h6的字型大小定義,建議放到專門的typography.css裡,不建議放在reset.css裡。所以這裡我同樣傾向於用YUI的策略,全部重設。
但是很不幸,在ie6/ie7當中,不論是strong還是h1-h6,亦或是em等元素,設定了inherit均無法繼承父元素屬性,依然保持自己的特色。這就帶來了瀏覽器差異,樣式重設本身是為了避免瀏覽器差異的,但現在帶來了瀏覽器差異,是萬萬不可取的。對於這個問題我考慮了很久,到底是為了統一所有瀏覽器都重設成normal(YUI的想法),還是放棄重設這些元素,讓他們順其自然,來保證在所有瀏覽器中樣式一樣(Eric的想法)。我最後決定採用YUI的做法。因為,無論重設成normal還是不重設,這些元素都無法繼承父元素屬性。既然如此,那麼退而求其次,保證這些元素都恢複到普通外觀,避免在設計的時候還要重設樣式。
不得不說,這種妥協是僅僅針對IE6和IE7的,也許在5年後,老闆和客戶都不要求支援IE7的時候,我們可以放心大膽得使用inherit了。
此外,YUI並沒有給code kbd samp tt 這幾個元素重設字型大小。但實際上在IE中,他們都會被縮小顯示。所以此處應當給予重設font-size: 100%;
7,行高(line-height)
對於行高,YUI並沒有給出重設定義,而Eric則給出了重設:
複製內容到剪貼簿
代碼:
body { line-height: 1; }
行高預設所有元素都會繼承的,所以給body設定行高為1就足夠了。通常行高設為1時候,英文照常閱讀,但中文就無法閱讀了,行間距過於緊密導致容易看錯行。通常在中文環境下得設定1.4到1.5才能是使用者正常閱讀。我建議是1.5,這樣算出來的值也是整數。比如字型大小12px的時候行高是18px,字型大小16px時行高24px。看起來也會比較舒服。此外,還有一個不設定成1的重要原因是:IE下,行高為1時,中文字頂部會被削掉幾像素,字型加粗時尤為明顯。所以,重設的原則是好的,但切不可重設為1。
8,列表樣式
YUI用了:
複製內容到剪貼簿
代碼:
li { list-style: none; }
Eric用了:
複製內容到剪貼簿
代碼:
ol, ul { list-style: none; }
儘管我沒有測試出YUI的有什麼問題,但我始終覺得設定ol和ul會比較穩妥。而且,波及的元素更少,效能應該更高一點。雖然下載量會多3位元組。
9,表格元素
在表格方面,都比較統一。均是:
複製內容到剪貼簿
代碼:
/* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; }
Eric還提醒到,需要在html中設定cellspacing="0" 來達到完美重設效果。
但此外YUI還設定了
複製內容到剪貼簿
代碼:
caption, th { text-align: left; }
讓caption和th元素不要置中。作為重設,是可取的。建議添加此規則。
10,上下標以及baseline
YUI寫成
複製內容到剪貼簿
代碼:
sup { vertical-align: baseline; } sub { vertical-align: baseline; }
似乎沒有最佳化,不知道為何沒有寫到一起去。而Eric則在最開始那條中就已經定義。而其中的問題是,YUI這樣定義了,但沒有重設字型大小,這點是有所遺憾的。既然是重設樣式,就徹底一些,所以建議改成這樣的:
複製內容到剪貼簿
代碼:
sup, sub { font-size: 100%; vertical-align: baseline; }
同樣對於Eric把所有元素都放到了Baseline上,包括上標下標。Eric的解釋是,強制讓設計師精確定位這些元素的垂直位移。
11,插入和刪除(ins/del)
對於這個問題,YUI直接清除了ins的底線和del的刪除線這兩個文本裝飾:
複製內容到剪貼簿
代碼:
del, ins { text-decoration: none; }
而Eric保留了刪除線:
複製內容到剪貼簿
代碼:
/* remember to highlight inserts somehow! */ ins { text-decoration: none; } del { text-decoration: line-through; }
如何取捨?我選擇Eric的,為什麼我這裡不追求完美的樣式重設了呢?很簡單,我這個reset的目標是為了讓我們寫頁面的時候盡量避免瀏覽器預設樣式,以及不同瀏覽器之間預設樣式差異帶來的問題。而del元素刪除線的文本裝飾,我相信沒有人會反對的。有人會加上其他樣式,比如字型變淡之類的,但對於del如此強語義的元素來說,沒有什麼比用刪除線更能表達含義的了。而不像上面那個focus樣式,未必人人喜歡虛線框。但似乎又沒有什麼瀏覽器預設不給del元素加刪除線,故這條可以省略。
所以,這裡我只重設ins樣式,別忘了給ins元素在等下也添加一些樣式。
12,引用元素的引號
某些瀏覽器中,q或者blockquote前後會出現引號。這個並不是誰都喜歡的。所以需要重設他。
YUI的比較簡單,只重設了q:
複製內容到剪貼簿
代碼:
q:before, q:after { content: ''; }
而Eric則比較周到,把q和blockquote都重設了。
複製內容到剪貼簿
代碼:
blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
OK,就決定用Eric的了,對於樣式重設,細緻一點周到一點總沒有錯。
13,連結
對於連結,YUI和Eric都沒有採取樣式重設,但從我思考許久後還是決定把連結樣式重設放進來。究其原因,還是因為樣式重設一來要徹底,二來對於連結樣式並非所有設計師都喜歡用底線裝飾。因此,我還是建議把連結的底線重設掉。
複製內容到剪貼簿
代碼:
a { text-decoration: none; }
但這樣做有點粗糙。真正有底線樣式的其實只有 :link和:visited所以改成下面這樣比較好:
複製內容到剪貼簿
代碼:
:link, :visited { text-decoration: none; }
此外,對於連結顏色,可以作為reset後急需設定的規則來處理。直接放入reset.css中不是很合適。
14,我的重設樣式
總結上面種種規則,這裡給出一下我的CSS重設規則,BSD協議發布,請隨意使用。測試樣本(這個是從YUI那裡複製過來的,感謝YUI為此做出的貢獻。)
下載:reset.css reset-min.css
複製內容到剪貼簿
代碼:
/* Copyright (c) 2009, Shawphy(shawphy.com). All rights reserved. http://shawphy.com/2009/03/my-own-reset-css.html Based on YUI http://developer.yahoo.com/yui/reset/ and Eric Meyer http://meyerweb.com/eric/tools/css/reset/index.html Licensed under the BSD License: http://creativecommons.org/licenses/BSD/ version: 1.1 | 20090303 */ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td { margin: 0; padding: 0; } fieldset, img { border: 0; } /* remember to define focus styles! */ :focus { outline: 0; } address, caption, cite, code, dfn, em, strong, th, var, optgroup { font-style: normal; font-weight: normal; } h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; } abbr, acronym { border: 0; font-variant: normal; } input, button, textarea, select, optgroup, option { font-family: inherit; font-size: inherit; font-style: inherit; font-weight: inherit; } code, kbd, samp, tt { font-size: 100%; } /*@purpose To enable resizing for IE */ /*@branch For IE6-Win, IE7-Win */ input, button, textarea, select { *font-size: 100%; } body { line-height: 1.5; } ol, ul { list-style: none; } /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; } caption, th { text-align: left; } sup, sub { font-size: 100%; vertical-align: baseline; } /* remember to highlight anchors and inserts somehow! */ :link, :visited , ins { text-decoration: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
15,完成一個初步的CSS架構
之前提到了,樣式重設作為一個所有項目可以使用的共性存在,而不同的項目應當有其個性。當然還有其他一些共性,不屬於樣式重設的部分,但同樣重要。再往下講就可以做一個CSS架構了。CSS架構所要考慮的內容遠比一個CSS Reset要考慮的多很多,這裡只是點到為止,不做更多展開。
layout.css
首先除了reset.css之外要建立的layout.css,這裡目前主要推薦放入.clearfix。清除浮動很重要。但這不屬於樣式重設,放在布局當中正合適。
複製內容到剪貼簿
代碼:
.clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .clearfix {display: inline-block;} /* Hides from IE-mac \*/ * html .clearfix {height: 1%;} .clearfix {display: block;} /* End hide from IE-mac */
此外,layout.css中還可以放入自己常用的布局,比如
複製內容到剪貼簿
代碼:
#wrap{margin:0 auto;width:960px;}
之類的規則。看個人喜好而定。
typography.css
這裡可以放置很多規則,非常重要的是以下三個:
:focus, a, ins
這三個是被重設掉的,但又很重要的內容,建議在reset之後立即在typography中設定全站樣式,保持樣式統一。
ins可以單獨設定, :focus 最好設定成跟 :hover一樣,而a的樣式還是按照LoVe,HAte的法則來設定。
h1-h6系列也是之前被重設掉的。可以考慮在這裡設定樣式。按網站特性來定。我個人是不喜歡全域定義hx系列的字型大小的,統一為100%我覺得挺好。
接下來要設定的是font-family屬性,可以參考射鵰的文章。另外,小麥的文章中提到,表單元素的字型在IE中都不能繼承父元素的字型,所以要單獨設定。
至於其他需要全域設定的,可以參考前文中的敘述,找到相應的部分添加到typography.css中即可。這樣就可以在保證reset.css通用性的情況下,使不同的項目又有個性。盡量保證reset.css在所有項目中都是一樣的。有利於項目的開發。最後不要忘記在寫表格的時候加cellspacing="0" 來達到完美重設效果。
16,探討
文章寫的比較倉促,也受限與本人能力所限,只能寫到這裡。歡迎留言探討,也可發郵件或上Twitter找我。以便進一步完善這個reset。謝謝。