css selectors 的語法及對應有效的瀏覽器 (css hacks)
- 說明:利用不同瀏覽器對 CSS selectors (指標) 支援程度的不同,使得 css 設計效果,可針對不同瀏覽器分別製作,一般稱這類處理方式為 css hacks (css 區隔設計) 或 css filters。
- 適合:有設計網頁及撰寫 css 語法經驗者。
- 難度:
- 更新:
- ie7
-
*+html selector {css 設計內容} - ie7, ie6 ~ ie5.5
-
*+html selector {css 設計內容} * html selector {css 設計內容} -
selector, {css 設計內容}(此詭異方法非 w3c 標準,卻很方便) - ie6 ~ ie5.5
-
* html selector {css 設計內容} - firefox, opera, safari, google chrome …等新式瀏覽器及 ie7 (含)以後版本
-
html>body selector {css 設計內容}或可簡化為*>selector {css 設計內容} - firefox, opera, safari, google chrome …等新式瀏覽器及 ie8 (含)以後版本
-
html>/**/body selector {css 設計內容} - firefox, opera, safari, google chrome, ie9 …等新式瀏覽器 (ie 以外) [參考說明]
-
html:root selector {css 設計內容} - ie8 [參考說明]
-
html>/**/body selector {css 設計內容} html:root selector {css 設計內容}(以此項覆蓋前項的定義,保留前項給 ie8) - firefox (Gecko series), google chrome2, safari4 [參考說明]
-
selector:not([att*=""]) {css 設計內容} - safari, google chrome [參考說明]
-
selector:not(:root:link) {css 設計內容} - Opera
-
html:root selector {css 設計內容} html:not(:link) selector {css 設計內容}(此項 Opera 無效) - Opera 9.5 (不含) 以前版本
-
html:first-child selector {css 設計內容}
註:新式瀏覽器如未加註版本,以近期較新版為準。
思考 - css hacks 與 css selectors
selector {css 設計內容} 這一部分和平常的 css 寫法完全一樣,而多加了一些有點陌生的符號 (紅色部分) ,變成「很另類」的 selectors ,就可以使設計內容在不同瀏覽器有效。可別小看這種 selectors 的寫法,它仍舊符合 w3c 規範的語法。注意語法中有空格的地方不能隨意省去,因為意義會是不同的。
css hack ie6
* html selector {css 設計內容}
正常 html 文件的最外層元素就是 html 這個「唯一的」元素 (elements) ,而 * html 的「*」指向 html 更外層的元素,當然是不存在的;但是 ie 6 會誤認為有效,所以就可以利用此法設計只會在 ie 6 呈現的 css 。
css hack ie7
*+html selector {css 設計內容}
正常 html 文件的最外層元素就是 html 這個「唯一的」元素,而 *+html 的「*+」指向 html 同層 (adjacent sibling combinator) 的元素,當然不存在;但是 ie 7 會誤認為有效,所以就可以利用此法設計只會在 ie 7 呈現的 css 。
css hack ie8
html>/**/body selector {css 設計內容}
html:root selector {css 設計內容}
第一項在 ie8 及其它新式瀏覽器有效,而第二項只在非 ie 的新式瀏覽器有效,所以只要在第二項定義 css 覆蓋掉第一項,就等同單獨為 ie8 指定。如,
html>/**/body #main {color:blue;}
html:root #main {color:inherit;}
ie8 字的顏色會以 blue 呈現,而其它瀏覽器則保留原來樣式。
又如,
#main {background:yellow;}
html>/**/body #main {background:orange;}
html:root #main {background:yellow;}
ie8 背景色會以 orange 呈現,而其它瀏覽器則為 yellow 。
css hack firefox, opera, safari, google chrome …等新式瀏覽器
html>body selector {css 設計內容}
html>body 在語法上可以說是多餘的,因為 html 文件的最外兩層就是 html 和 body 這兩個唯一的元素,所以加不加這段,結果其實是一樣的;但是由於 ie 6 沒有支援有 「>」 符號 (child combinators) ,就可以利用此方式為 ie 6 以外的瀏覽器定義 css 設計。運用同樣的道理,大部分時候,可以將它簡化寫成 *>selector ,只是使用時要注意 selector 所指向的元素的階層關係,如果覺得搞不清楚,最好還是使用前者語法比較保險。
html>/**/body selector {css 設計內容}
html>/**/body 和 html>body 其實是同樣意義,因為符號 /**/ 只是 css 定義裡的註解語法,瀏覽器應當忽略它不會影響原有的內容,但是 ie 7 卻會因為這個位置加了註解符號而變成無效。
css hack non-ie (非 ie)
html:root selector {css 設計內容}
通常運用 ie 未支援的 css selectors 語法,就可以為 ie 以外的瀏覽器 (non-ie browsers) 設計。
:root pseudo-class 在 ie 8 仍未支援 (ie 9 已支援) ,所以語法中 html:root 就可以簡單地將 ie 排除在外了。 ie 還有其它尚未支援的 selectors 也都可以派上用場,像是運用 :not() negation pseudo-class ,可以寫成如 html:not(:first-child) selector 或是 html:not(:empty) selector ,也都可以將 ie 排除。 ie 的支援程度總會較其它新式瀏覽器慢半拍,依循這個邏輯,就可以很輕易與 ie 區隔設計了。
css hack firefox (Gecko 核心的瀏覽器), google chrome2, safari4
selector:not([att*=""]) {css 設計內容}
這個…真有點複雜,先對照例子看看。
xhtml-
<div class="content"> <p>花徑不曾緣客掃,蓬門今始為君開。</p> </div> css-
.content:not([class*=""]) {background: lime;}
需要注意的是語法中 [att*=""] 的 att 必須對應元素已有定義的屬性 (attributes) ,如例中 div 元素的 class 屬性。如果對應的是元素尚未定義的屬性,把上例改成 .content:not([id*=""]) ,雖然語法上沒有錯誤,但是這會使其它新式瀏覽器也同樣有效,就不是僅僅 hack firefox ,而是 hack ie 以外的瀏覽器了 (ie8 尚未支援 :not() negation pseudo-class) 。還有要小心 :not 前面沒有空格。
css hack safari, css hack google chrome
selector:not(:root:link) {css 設計內容}
- 對照前一個
xhtml例子,css可以是 -
.content:not(:root:link) {background: orange;}
:not() negation pseudo-class 括號內的引數 (argument) ,依據 w3c 的說明,應為 a simple selector (簡單指標) ,但是未明確指出 a sequence of simple selectors (簡單指標串) 是否可以,像是 #main.box, *.content, *[class^=part], 或 a:link 之類。
目前僅有 safari 及 google chrome 支援 :not() 括號內引數可以是 a sequence of simple selectors ,所以就利用這個特點來作區隔。依照這個邏輯,寫法就可以很多彈性變化了,如 selector:not(*:root), selector:not(*.xyz), 或 selctor:not(*[title=xxx]) ,都一樣有效。甚至改成 html:not(*:empty) selector{css 設計內容} 也是可以的,既豐富又有趣。另外,需要小心如果引數裡有元素名稱的 type selector (型態指標), opera 會造成之後 css 設計無效。
css hacks 處理最小高度 (min-height) 及高度 (height) (hack ie bugs)
提到有關 css 指定「高度」的問題,始作俑者就是 ie 6 。 ie 6 並未支援 min-height 特性,這也無可厚非,不過最糟糕的是把 height 特性拿來代替 min-height 特性,這也就造成廣大仰賴 ie 的網頁設計者,遭遇後來新版 ie 及其它新式瀏覽器時,發生版面內區塊的內容超出、重疊、或擠成一堆的狀況。實際上 ie 6 的呈現方式是錯誤的,以前看不出來就算了,現在就不能繼續將錯就錯下去了,幸好,我們可以運用 css hack 將 ie 6 的定義區隔起來。
- 例如
xhtml -
<div id="main"> <p>勸君更盡一杯酒,西出陽關無故人。</p> </div> css-
#main {min-height: 200px;}
這是常會遇到的狀況,網頁設計者可能因設計需要而必須指定元素 div 有一個高度 (如 200px),但是如果「內容」(content) 增加時,可能會超過 200px ,也希望 div 的高度會隨著「內容」增高。正常狀態下,我們只需要單純地以 #main 這個 css selector 指定 min-height 就可以了,如例中 #main {min-height: 200px;} 。不過, ie 6 沒有支援 min-height 特性,所以對該項定義就不會有作用。如果要讓 ie 6 也能達到同樣效果,就必須用到 height 特性,但是直接增加 height 將會使所有瀏覽器同時有效,如:
- 這樣的
css不會是想要的結果 -
#main { min-height: 200px; height: 200px; }
指定了 height 也就是 div 的高度被「固定」了,那麼 min-height 就沒意義了,就算內容增加也不會改變「固定的」高度 (如 200px) ,過多的內容只會以「越出」 div 的高度範圍顯示,就可能與其它的區塊重疊,看起來就像擠成一堆。因此, height 必須另外區隔給 ie 6 才可以達到我們想要的結果。
- 正確的
css -
#main {min-height: 200px;} * html #main {height: 200px;}/*僅 ie 6 ~ ie 5.5 有效*/
ie 6 對第一項定義的 min-height 沒有作用,但是會讓第二項有效;而新式瀏覽器只會讓第一項的定義有效,但第二項不會作用。如此就是運用 css hack 的技巧,讓 ie 6 能以 height 達成「最小高度」的目的,但是又不影響其它瀏覽器。
本篇所提 css hacks 技巧,主要是設計者可以經由 css selectors 的變化,做到在不同瀏覽器可有不相同的 css 設計,提供設計者很大的發揮空間,而且與平常定義 css 特性完全相同;當然, css hacks 還有其它不同方式,設計者應視狀況使用,如何善加運用還是決定在設計者。
- 參考資源
-
- CSS hacks - 多種不同方式的詳細研討,內容較繁長 (英文) 。
- centricle CSS filters - 各種瀏覽器及版本列表,完整但較不易理解 (英文) 。
- 條件式註解 Conditional Comments - ie 專屬的 html 方式。
- Thoughts on IE hack management - 各種方式比較與說明 (英文) 。

很仔細的分析,又考量各種瀏覽器...您真的很用心~~
您好~感謝分享唷!!想請教一個問題~就是我部落格上面的圖片為什麼縮在一角呢??要如果讓它怖滿呢??感恩^^
標頭的照片目前是定義在 #header 的背景,照片實際尺寸是 1680x1050 ,而 #header 區域的尺寸 850x465,兩者不相符且差距甚遠。 目前多數瀏覽器尚未支援 css 背景圖片尺寸可自動縮放至與所在區域相同,所以只能先修改圖片到適當的大小。
請問ie8是否不支援高度延伸問題?
不是很懂你的意思? 如果「區塊」指定了「固定的高度」,當內容超過其高時,「本來」就不會延伸,上文「末段」就有清楚的解釋了。
IE6定義了height後,div還是會隨內容撐大嗎?
是的,在 ie6 就是把 height 當成最小高度,可以自己實際測試就會更了解喲。
html>/**/body body { text-align: center; } html>/**/body .1 { background-image: url(../images/0_01.jpg); background-repeat: no-repeat; height: 377px; width: 980px; } html>/**/body .2 { background-image: url(../images/0_02.jpg); height: 652px; width: 227px; } html>/**/body .3 { background-image: url(../images/0_03.jpg); height: 652px; width: 753px; } html>/**/body .4 { background-image: url(../images/0_04.jpg); background-repeat: repeat; height: 6px; width: 980px; } html>/**/body .5 { background-image: url(../images/0_05.jpg); height: 324px; width: 980px; } html>/**/body #6 { height: 1015px; width: 555px; background-position: center; } html>/**/body #apDiv1 { position:absolute; width:622px; height:1026px; left: 268px; top: 335px; float: right; } html:root body { text-align: center; } html:root .1 { background-image: url(../images/0_01.jpg); background-repeat: no-repeat; height: 377px; width: 980px; } html:root .2 { background-image: url(../images/0_02.jpg); height: 652px; width: 227px; } html:root .3 { background-image: url(../images/0_03.jpg); height: 652px; width: 753px; } html:root .4 { background-image: url(../images/0_04.jpg); background-repeat: repeat; height: 6px; width: 980px; } html:root .5 { background-image: url(../images/0_05.jpg); height: 324px; width: 980px; } html:root #6 { height: 1015px; width: 555px; background-position: center; } html:root #apDiv1 { position:absolute; width:622px; height:1026px; left: 268px; top: 335px; float: right; } body:not([att*=""]) { text-align: center; } .1:not([att*=""]) { background-image: url(../images/0_01.jpg); background-repeat: no-repeat; height: 377px; width: 980px; } .2:not([att*=""]) { background-image: url(../images/0_02.jpg); height: 652px; width: 227px; } .3:not([att*=""]) { background-image: url(../images/0_03.jpg); height: 652px; width: 753px; } .4:not([att*=""]) { background-image: url(../images/0_04.jpg); background-repeat: repeat; height: 6px; width: 980px; } .5:not([att*=""]) { background-image: url(../images/0_05.jpg); height: 324px; width: 980px; } #6:not([att*=""]) { height: 1015px; width: 555px; background-position: center; } #apDiv1:not([att*=""]) { position:absolute; width:622px; height:1026px; left: 268px; top: 335px; float: right; } *+html body { text-align: center; } *+html .1 { background-image: url(../images/0_01.jpg); background-repeat: no-repeat; height: 377px; width: 980px; } *+html .2 { background-image: url(../images/0_02.jpg); height: 652px; width: 227px; } *+html .3 { background-image: url(../images/0_03.jpg); height: 652px; width: 753px; } *+html .4 { background-image: url(../images/0_04.jpg); background-repeat: repeat; height: 6px; width: 980px; } *+html .5 { background-image: url(../images/0_05.jpg); height: 324px; width: 980px; } *+html #6 { height: 1015px; width: 555px; background-position: center; } *+html #apDiv1 { position:absolute; width:622px; height:1026px; left: 268px; top: 335px; float: right; }
1.css selector hack 只需要針對不同的 css properties 作區隔,相同的 properties 就不需要 hack 了,這樣反加重 css 檔的累贅。 2.html>/**/body 已經就是指 body 了, html>/**/body body 變成兩個 body 了。 3. html 不論是 id 或 class 的命名,首字只能是英文,不能是數字或特殊符號。 4.<!-- --> 這是 html 的註解語法,寫在 css 區段會造成錯誤; css 的註解是 /* */ 或 // 。 5.在同樣的元素指定 position:absolute 及 float ,最後只有 position 有效, 加 float 是多此一舉。 6. att 指的是已定義的 html attribute 名稱,請看說明,或 http://boohover.pixnet.net/blog/post/33827991 這篇。 問問題至少也留個稱呼,這是基本禮貌吧!
這編是我留的: (抱歉,找了一整個下午了..到半夜就頭昏昏,沒登入就留問題) 請教CSS瀏覽器的區隔...看了以上內容不知是否做對了, 請老師解惑也.... 謝謝老師~ 因為剛學不久,所以很多不懂.. >"< 可是我會認真吸收的~ 謝謝老師~ 有不會的再請教您 ^___^ (如方便的話可以留msn嗎?不方便的話也沒關係. ) yucih
在上面banner處,我的名稱裡的連結就是了。其實在msn很容易就可以搜尋找到我的,不過,我沒辦法常在線上就是了。 或是也可以試試 facebook ,我剛開立的研討區 http://www.facebook.com/groups/205123879529001/