css selectors 的語法及對應有效的瀏覽器 (css hacks)

  • 說明:利用不同瀏覽器對 CSS selectors (指標) 支援程度的不同,使得 css 設計效果,可針對不同瀏覽器分別製作,一般稱這類處理方式為 css hacks (css 區隔設計) 或 css filters
  • 適合:有設計網頁及撰寫 css 語法經驗者。
  • 難度:等級5
  • 更新:
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 hackscss 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 文件的最外兩層就是 htmlbody 這兩個唯一的元素,所以加不加這段,結果其實是一樣的;但是由於 ie 6 沒有支援有 「>」 符號 (child combinators) ,就可以利用此方式為 ie 6 以外的瀏覽器定義 css 設計。運用同樣的道理,大部分時候,可以將它簡化寫成 *>selector ,只是使用時要注意 selector 所指向的元素的階層關係,如果覺得搞不清楚,最好還是使用前者語法比較保險。

html>/**/body selector {css 設計內容}

html>/**/bodyhtml>body 其實是同樣意義,因為符號 /**/ 只是 css 定義裡的註解語法,瀏覽器應當忽略它不會影響原有的內容,但是 ie 7 卻會因為這個位置加了註解符號而變成無效。

css hack non-ie (非 ie)

html:root selector {css 設計內容}

通常運用 ie 未支援的 css selectors 語法,就可以為 ie 以外的瀏覽器 (non-ie browsers) 設計。

:root pseudo-classie 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 之類。

目前僅有 safarigoogle 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 hackie 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 還有其它不同方式,設計者應視狀況使用,如何善加運用還是決定在設計者。

參考資源
散佈、展示請參閱 Creative Commons 授權條文,禁止重混,引述請增加原文連結。
文章標籤

不老師 發表在 痞客邦 留言(6) 人氣()