如何組織CSS-分層
應用 css 的能力分兩部分:一部分是css的API,重點是如何用css控制頁面內元素的樣式;另一部分是css架構,重點是如何對 css 進行組織。如何組織 css 可以有多種角度,例如按功能劃分,或者按區塊劃分。這裡講一下 base.css + common.css + page.css 的組織方法。將網站內的所有樣式,按照職能分成三大類:base、common、page,這三者是層疊結構。
1、base 層-精簡通用
位於三者的最底層,提供 css reset 功能和粒度最小的通用類——原子類。這一層會被所有頁面引用,是頁面樣式所需依賴的最底層,不同風格的網站可以使用同一個 base 層,所以,應具有高度可移植性,力求精簡和通用。該層相對穩定,基本不需要維護,可以簡單地放在一個檔案裡,如 base.css。
css reset 即一開始就將瀏覽器的預設樣式全部去掉,就是通過重新定義標籤的樣式,“覆蓋”掉瀏覽器提供的預設樣式。可以將常用的標籤顯式地羅列出來,避免使用“*”,如來自於 YUI 的部分 css reset 的代碼:
/*CSS reset*/
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}
table{border-collapse:collapse;border-spacing:0;}
fieldset,img{border:0;}
address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}
ol,ul{list-style:none;}
caption,th{text-align:left;}
h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}
q:before,q:after{content:”;}
abbr,acronym{border:0;}
通用原子類是一系列常用的基本類,包括:文字、定位、長度和邊距,由於其原子性,除少數特殊類,大部分都只包含一句 css,如:.f12{font-size:12px;},由於其通用性,在保證命名有語義前提下,命名應盡量簡短,如 paddingtop20 可以寫成 pt20。通用原子類裡有幾個類較特殊,特別說明一下:
1).fl 類和.fr 類:除了設定 float:left 和 float:right 之外,還應設定 display:inline,可以解決 IE6 的雙外邊距 Bug。
.fl{float:left;display:inline;}
.fr{float:right;display:inline;}
2).bc 類:為使區塊層級元素置中,還要設定寬度,可以把它和 .w100 等類同時使用,如:
.bc{margin-left:auto;margin-right:auto;}
.w100{width:100;}
3).clearfix 類:用於在父容器直接清除子項目浮動。
4).zoom 類:設定樣式是 zoom:1,它是 IE 的專有屬性,用以觸發 hasLayout。
2、common 層-組件級,模組化,重用
位於中間,提供組件級的 css 類。可以將頁面內的元素拆分成一小塊功能和樣式相對獨立的小“模組”,將大量重複地“模組”視為一個組件,放在 common 層裡(“模組化”可以從樣式和行為兩個層面來考慮,與 common 層相關的是樣式的模組化)。common 層相當於 MVC 模式中的 M(Model,模型),需儘可能將內部實現封裝。
common 層是網站級的,不同的網站有不同的 common 層,同一個網站只有一個 common 層,可以放在一個檔案裡,也可按功能劃分放在多個檔案裡。在團隊合作中,common 層最好由一個人負責,統一管理。
3、page 層
網站中非高度重用的模組,可以放在 page 層裡。page 層位於最高層,提供頁面級的樣式。如果網站規模不過於龐大,可以將所有 page 層放在一個檔案裡,根據頁面配上注釋,分塊書寫,便於維護。page 層 css 檔案應越簡越好,能用 base 層和 common 層的 css 解決的,盡量不要用到 page 層。
避免濫用子標籤
低權重原則。
能用組合,不用繼承。
駝峰命名用於區別不同單詞,劃線用於表明從屬關係。
CSS sprite
1.技術是針對作為背景的圖片,對與html文檔<img src=""/>設定的圖片,不能合并到CSS Sprite大圖,否則圖片會影響頁面可讀性。
2.對於橫向和縱向都平鋪的圖片,也不能使用CSS sprite;如果是橫向平鋪的,只能將所有橫向平鋪的圖合并成一張大圖,只能豎直排列,不能水平排列;如果是縱向平鋪的,只能將所有縱向平鋪的圖合并成一張大圖,只能水平排列,不能豎直排列。
3.CSS sprite的圖片定位可以使用bg2css小工具快速定位background-positon座標,有利於提高開發速度。
4.好處是減少HTTP請求數減輕伺服器壓力,缺點是降低開發效率、增加維護難度。CSS Sprite大圖中每個圖片的維護改動都要謹慎,防止影響周圍的圖片。
網站是否使用CSS Sprite技術,主要取決於網站流量。
流量大的網站好處明顯:減少HTTP請求數量,減輕伺服器壓力;(電商,微博,輕博,社區)
流量不大的網站代價很大:降低開發效率,增大維護難度(後台管理系統一般不適合使用)
CSS hack1.IE條件注釋法
該方法安全性、相容行好,也是微軟推薦的hack方法,但是不利於開發維護,需要維護多份css檔案。比如涉及到針對不同版本IE的css。
<!--[if IE]><![endif]--> 只在IE下有效
<!--[if IE 6]><![endif]--> 只在IE6有效
<!--[if gt IE 6]><![endif]--> 只在IE6以上版本有效
注意:結合lte(小於等於)、lt(小於)、gte(大於等於)、gt(大於)、!(非)關鍵字使用。
2.選擇符首碼法
“*html” 首碼只對IE6生效 "*+html"首碼只對IE7生效
.test{width:80px;} /*IE 6 7 8*/
*html .test{width:70px;} /*IE6*/
*+html .test{width:60px;} /*IE7*/
缺點:不能保證IE9,10不識別*html,*+html,有向後相容風險。
3.樣式屬性首碼法:
如“_”只在IE6下生效,“*”在IE6和IE7下生效。同樣有向後相容隱患。
.test{width:80px;*width:70px;_width:60px;}
可用於內聯樣式:<div style="width:80px;*width:70px;_width:60px;"></div>
由於IE條件注釋法不利於開發維護,實際中常用的hack方法常常是後兩者。
display:inline-block 和 hasLayout區塊層級元素、行內元素
區塊層級元素會獨佔一行,預設寬度自動填滿其父元素寬度,可以設定width、height、margin、padding屬性;
行內元素一行排滿才會換行,寬度隨元素內容多少變化,設定width、height屬性無效,只有水平方向的margin、padding邊距有效果。
常見的區塊層級元素有div、p、table、fieldset、form、ul、ol、dl、h1~h6、hr、pre、address、blockquote、center、dir、menu、noframes、noscript。
常見內嵌元素有input span strong em a abbr acronym br img select textarea等等。
可以通過修改display屬性值轉行塊元素和行內元素。
display的值除了block和inline,還有其他值,例如list-item、teble-cell等,但因為IE6和IE7瀏覽器支援的display類型很少,所以為相容IE,真正能用的display類型只有block、inline和none三種。
IE6、IE7支援但不完全支援display:inline-block屬性,但IE8+和FF等標準瀏覽器支援。
display:inline-block,行內的區塊層級元素,它擁有區塊層級元素的特點,可以設定長寬,可以設定margin和padding值,但它卻不是獨佔一行,它的寬度並不佔滿父元素,而是和行內元素一樣,可以和其他行內元素排在同一裡。它集區塊層級元素和行內元素的特點於一身,是個非常有用的display類型
讓IE6、IE7支援display:inline-block
利用hasLayout可以再不支援display:inline-blcok的IE6和IE7下類比出display:inline-block的效果,實現IE6、IE7、IE8+和Firefox都相容的display:inline-block的應用。但是也有一些問題需要特別注意:
- 在IE6、IE7中不識別display:inline-block屬性,但使用inline-block屬性在IE下會觸發layout,從而使內嵌元素擁有了display:inline-block屬性的表症。
- 在IE5.5中開始支援 inline-block 。你可以使用 inline-block 使對象獲得布局而無需指定確切的高( height )和寬( width )。
- IE6/IE7的inline-block屬性只對原生預設的內嵌元素(span, a, em......)有效,對於區塊層級元素(div,p,ul......)無效。 In IE 6 and 7 inline-block works only on elements that have a natural display: inline.IE doesn't apply the value inline-block for the CSS display property on HTML elements that default to block level.
- 兩個結論: 1、IE6/7不識別inline-block,只是觸發了layout,表現跟inline-block塊元素表現一樣。2、IE6/7不完全支援inline-block,只對內嵌元素有效。
- 看官方的說法,確證對inline-block的認識。The following table shows Cascading Style Sheets (CSS) properties and corresponding values that, if set, cause an element to have layout.
- 下表列出一些CSS屬性及其值,以下屬性一旦設定,將觸發元素的layout:
CSS propertyValue
display inline-block
height any value
float left or right
position absolute
width any value
-ms-writing-modetb-rl
zoom any value
- 延伸問題:IE下塊元素如何? display:inline-block 的效果?
有兩種方法:
1、先使用 display:inline-block 屬性觸發塊元素,然後再定義 display:inline,讓塊元素呈遞為內聯對象(兩個display 要先後放在兩個 CSS 聲明中才有效果,這是 IE 的一個經典 bug ,如果先定義了 display:inline-block,然後再將 display 設回 inline 或 block,layout 不會消失)。代碼如下:
div {display:inline-block;}
div {display:inline;}
說明:在IE下,display: inline-block只是觸發了元素的layout。比如將display: inline-block給到div上,只能保證這個div擁有塊元素的特徵(可以設定寬度,高度等),但是還是行布局(產生換行)。接下來要設定display: inline,更改這個div的布局為內聯布局(不產生換行)。
2、直接讓塊元素設定為內聯對象呈遞(設定屬性 display:inline),然後觸發塊元素的 layout(可使用zoom:1 等)。代碼如下:
div {display:inline; zoom:1;}
hasLayout
hasLayout設計的初衷是用於輔助區塊層級元素的盒子模型的,它是用於區塊層級元素的。如果用於行內元素,會引發一些特殊效果。(結合上面紅色字型理解)
設定寬高屬性width、height值都可以觸發hasLayout,但是有時候帶來副作用,現在常用zoom:1;來觸發,極少數非常複雜的css設定情況zoom無效的時候,需要藉助更為強大的“position:relative”來觸發hasLayout。
haslayout 是Windows Internet Explorer渲染引擎的一個內部組成部分。在InternetExplorer中,一個元素要麼自己對自身的內容進行計算大小和組織,要麼依賴於父元素來計算尺寸和組織內容。為了調節這兩個不同的概念,渲染引擎採用了 hasLayout 的屬性,屬性值可以為true或false。當一個元素的 hasLayout屬性值為true時,我們說這個元素有一個布局(layout)。
詳見:http://baike.baidu.com/view/2945869.htm
http://www.cnblogs.com/yupeng/archive/2011/04/11/2012996.html
系列知識連結
[原]《Web前端開發修鍊之道》-讀書筆記HTML部分
[原]《Web前端開發修鍊之道》-讀書筆記JavaScript部分
[原]JavaScript必備知識系列