Box Model (框框模型) 是什麼?

請參閱👉新版解說。包含 3D 動畫展示。

  • 說明:css box model 描述出文件中,元素 (elements) 所形成的最基本矩形區域 (boxes) 及專有名詞;此為呈現視覺性 (visual) 版面的重要基礎。
  • 適合:有 htmlcss 語法基礎概念者。
  • 難度:等級2
  • 更新:
 

只要有東西在版面上描繪 (可以把版面想成一張空白的紙) ,就一定會佔有版面上某些空間,縱使是一個字,也至少就佔了一個字的矩形區域,而這樣的區域被定義為「」 (boxes) 。

文件內某「一個」元素的「框」 (box) 可由四個層疊的 (nested) 區域所組成:該元素所包含的「內容」 (不論是單純的文字,或是其它元素) 形成最內層的區域,就是 content area (內容區) ,依序向外一層一層圍繞為 padding area, border area, margin area (補距區 - 邊線區 - 邊距區) 。

區與區之間可分別由 css 指定 padding, border, margin 特性 (property) 來改變相互的距離,而每種特性定義都有上下左右四向,可由版面設計者指定各不相同的距離 (說成是厚度、寬度也可以) ,當然也可以沒有距離,運用這樣的概念進而改變版面上整組 box 的尺寸及呈現。

由內向外四個區都各自有「四邊」形成緊鄰的框,標準的名稱依序為:

content edge or inner edge (內緣-圖中綠線)
具有寬 (width) 及高 (height) 的 content area 四邊,與 padding area 交界處;四邊圍成的區域稱為 content box
padding edge (補距外緣-圖中紅線)
padding area 四邊,與 border area 交界處;四邊圍成的區域稱為 padding box
border edge (邊線外緣-圖中藍線)
border area 四邊,與 margin area 交界處;四邊圍成的區域稱為 border box
margin edge or outer edge (框外緣-圖中深灰線)
margin area 四邊,也是整個框 (box) 的最外緣;四邊圍成的區域稱為 margin box

margin box 來說,永遠呈現透明 (因此能看到其背後的內容);在元素上定義背景 (background) 呈現在 border box, padding box, 及 content box 的區域內。而 content box 的「內容」當然是呈現在背景的前面。

思考 - Box Modelcss 版面視覺設計

Box 在版面編排上可以說是無所不在,就算「內容」 (content) 是單單一個字都具有 box,佔有一小塊矩形區域;當然,也能由 css 個別指定不同的 padding, border, margin。如果 padding, border, margin 的距離都是「零」,那麼當然, padding box, border box, margin box 的大小就會與 content box 所擁有的寬高一樣。

 

許許多多字的 Box 就如同「堆積木」,一個個相鄰著由上而下堆疊起來 (書寫方向為由左向右、由上至下時),將內容有規則地分布在版面上,而這個規則就是設計者以 css 定義的呈現方式。

行內層級 (inline-level) 與區塊層級 (block-level) 呈現模式不同

許多的「字」結合起來可以產生「段落」,段落則再形成更大的矩形 box ,將文字圍繞起來。

例如 xhtml
<p>
看到竹子想到王陽明。看到桃花想到桃花源記。看到蓮花想到周敦頤。<em>看到荷花想到何仙姑。看到玫瑰想到愛神。看到菊花想到陶淵明。</em>看到百合想到香水。~節錄自 monica 「聯想的遊戲」
</p>

元素 p 代表段落,一般以區塊層級 (block-level) 方式呈現,會是一個「獨立」的矩形 box ,可特別稱為 block boxes (圖中綠線) 。而 p 所包含的「內容」 (content) 可想像成,由「三節」行內層級 (inline-level) 或文字層級 (text-level) 的文字組成,三個行內層級元素 (inline-level emements) 當然都有自己的 box ,可特別稱為 inline boxes ,以一個個「自動緊接」的方式呈現,與 block boxes 圍成「一區」的矩形不盡相同。

  1. 看到竹子想到王陽明。看到桃花想到桃花源記。看到蓮花想到周敦頤。
  2. <em>看到荷花想到何仙姑。看到玫瑰想到愛神。看到菊花想到陶淵明。</em>
  3. 看到百合想到香水。~節錄自 monica 「聯想的遊戲」
 

1 與 3 只是文字,屬於文字層級 (text-level) 元素,雖然有「自然產生」的 inline boxes ,不過由於沒有賦予特定的元素名稱,也可稱為「不具名 (anonymous) 元素」,所以無法經由 css selectors 為其指定 padding, border, margin 等;而 2 因為已被指定成 em 元素 (行內層級元素) ,就可以由設計者定義。

行內層級元素無法容納在一行內時, inline boxes 就會拆斷成二行或是數行,範例中的 em 元素就可能拆成二行或是三行的矩形框 (圖中藍線),不再是標準的一塊矩形而已了。 inline boxes 的「左邊」在該元素第一行起始的左方,「右邊」在最末行結尾的右方,所以如果指定「左或右」的 padding, border, margin 時,只會在第一行和最末行作用,不會在各分行的「拆斷處」產生;指定「上或下」會在各行產生 (當然,依據 margin 規則,定義「上或下」不會作用在「不可替換」行內元素 (non-replaced inline elements)) 。

抽象的 line boxinline boxes 而產生

line box 像是抽屜,也像骨架一般,將行內元素分成一層一層「收納」,如前例 (圖中紅線),一層放不下就會轉到下一層。通常會看到行與行之間其實會有些許的空隙,不只是「字」的高度而已,這就是 line box 這個抽屜的高度,並不是 inline box 的高度。所以,實際上 inline boxes 是存在於一行一行抽象的 line box 裡,而 line box 一行行疊成區塊層級元素 (如前例的 p) 。 line box 由上向下,一行緊鄰著一行,而且永遠不會相互重疊。

line box 與前面所講的 box 不同, line box 是因行內元素所產生的抽象空間,只是區塊層級元素 (block-level elements) 的 box model 一部分而已,不是真實的元素,所以也不可能為其指定 box 的各項數值 (如 width, height, padding, border, margin 等) 。 line box 的寬度根據其容納區 (containing block) 所決定,而高度則由 css line-heightvertical-align 的定義來決定。

多重的 block boxes 像洋葱一層包著一層

實際上,每一個區塊層級元素 (block-level elements) ,必然會由另一個區塊層級元素包圍,根元素除外 (root element, html 文件指的就是 html 元素) ,所以,許多個 block boxes 一層一層包圍起來時就好似洋葱的構造。

例如 xhtml
<blockquote>
<h1>聯想的遊戲</h1>
<p>看到三國演義想到七俠五義。看到紅樓夢想到牡丹亭。看到山海經想到鏡花緣。看到芭蕉扇想到鐵扇公主。看到豬八戒想到沙悟淨。看到孫悟空想到如來佛。看到史記想到司馬遷。看到船想到孔明借箭。看到滿山秋色想到最愛的詩人王維。看到赤子純真一般的畫想到豐子愷。看到李叔同想到大護法夏丏尊。~節錄自 monica 「聯想的遊戲」</p>
</blockquote>
 

很明顯地, h1, p, blockquote 都是區塊層級元素h1p 的「內容」 (content) 僅包含著行內層級的元素,就像前面一樣,兩者各自擁有矩形的 block box ,也都可以各自指定 padding, border, margin (圖中紅線) 。而 blockquote 從外包圍著 h1ph1p 成了 blockquote 的「內容」 (content) ; blockquote 形成另一個 block box (圖中綠線) ,當然也可以指定 box 的各項數值。

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

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

為物件指定 hasLayout property

  • 說明: ie 專有用法 (ie only)。部分 ie 專有的特性 (property) ,如 filters and transitions ,有作用的必要條件就是指定 hasLayout 性質。 hasLayout 性質本來是微軟為了補救 ie 內部不完善所自創的,並非 w3c 標準,所以有時用起來覺得相當無厘頭。但神奇地, ie7 以前舊版衍生的網頁不正常呈現問題 (ie bugs),大多數竟可由指定 hasLayout 來解決。
  • 適合:有 htmlcss 語法撰寫基礎者。
  • 難度:等級4
  • 更新:
  • 適用:ie7 ~ ie5.5

hasLayout "property" 和 css property 雖然英文名稱一樣,但實際上不太相同。 hasLayout 本身並非 css 特性的一種,所以沒辦法直接定義物件的 css 特性 hasLayout 的值 (value),而是間接以其它的 css 特性指定在物件上,使該物件符合 hasLayout ,所以我比較傾向稱它是 hasLayout 「性質」。

符合以下任一種 css 特性及值的定義方式,物件即是 hasLayout (有編置) :
ie 7 增加了幾個新的指定方式:

認識 hasLayoutcss 規則

上述規則有的看起來有點含糊,有的好像又很陌生,那要怎麼正確定義物件 hasLayout 呢?

heightwidth 特性只需要指定一個「具體值」 hasLayout 就有效了,如 width:80%; ,甚至 height:0; 也可以喲。 min-height, max-height, min-width, max-width 等特性也可以如法炮製,如 max-width:100em; 或是 min-height:0;。需要注意的是依據 css 規則,這類特性在行內層級 (inline-level) 元素不會有作用。

float 特性通常有 float:left;float:right; 二種值都可以達成 hasLayout

position:absolute;position:fixed; 算是同類型的定義,二者都能使 hasLayout 有效,只是 "fixed" ie 6 沒支援。

zoom 特性看名稱就知道是縮放大小,像 height 之類一樣,只要有「具體值」 hasLayout 就有效了,而且行內層級元素也能作用,如 zoom:0.9; 。撰文時這個特性僅為 ie 專用 (ie only) ,非 w3c 標準,所以非 ie 瀏覽器 (firefox, opera, safari, …) 沒有支援也就不會有任何影響。

指定 overflow 特性通常有 overflow:auto;, overflow:hidden;overflow:scroll; 三種值,雖然 ie 6 有支援,不過目前只有 ie 7 會讓 hasLayout 有效。而 overflow-xoverflow-ycss3 的規則,撰文時僅 iefirefox 支援。

writing-mode 特性也是 css3 的規則,比較少會用這個特性指定 hasLayout ,撰文時也僅 ie 支援。

物件原則上預設都是不具 hasLayout 性質,所以我們才需要特別指定 hasLayout ,但是有部分元素在 ie 預先就已內定永遠為 hasLayout ,明細可參閱 Microsoft 官方文件

卸除 hasLayout 性質

當然,可以反向定義物件 hasLayout 性質為無效,不過部分元素已內定 hasLayout 就沒辦法使其失效的。會用到卸除 hasLayout 的時機,都是針對已指定過 hasLayout 的物件,卻可能因某些目的而必須轉回無 hasLayout 。所以,通常只要將原先定義 css 特性,再重新定義回「預設值」,就會讓物件的 hasLayout 性質無效了。

css 特性及值再定義成以下任一種方式,即可使 hasLayout 無效 (卸除) :
  • height: auto;
  • width: auto;
  • max-height: none;
  • max-width: none;
  • float: none;
  • position: static; (預設值)
  • overflow: visible;
  • overflow-x: visible;
  • overflow-y: visible;
  • zoom: normal;
  • writing-mode: lr-tb; (預設值)

舉例子看看就明瞭了:

xhtml
<div id="main">
 <p>漁舟逐水愛山春,兩岸桃花夾去津。坐看紅樹不知遠,行盡青溪不見人。</p>
 <p>山口潛行始隈隩,山開曠望旋平陸。遙看一處攢雲樹,近入千家散花竹。</p>
 <p class="extract">節錄自:王維的桃源行</p>
</div>
css (例一)
#main p {float:left;}
#main .extract {float:none;}
css (例二)
#main p {zoom:125%;}
#main .extract {zoom:normal;}

兩例的 css 都類似情形,前一條定義先讓全部三段 p 成為 hasLayout ,後一條再讓最後一段的 hasLayout 無效。需要了解的是,卸除 hasLayout 的規則是定義在 hasLayout 規則之後的另一組指標 (selectors) 裡,而且是取代先前「相同的」特性,前面用 float 指定,後面就要用 float 來卸除,這本來就是依循 css 的規則,只是再提醒一下而已。

無法卸除 hasLayout 的定義

display:inline-block; 指定 hasLayout 後,就沒辦法卸除,無論再定義回 display:inline;display:block;hasLayout 依然維持有效,所以上述卸除規則沒有這項,這點必須注意。

由於 min-heightmin-width 的預設值是 0,所以縱使再定義為 min-height:0; (具體值),也無法卸除 hasLayout 。但是 ie 卻接受 min-height:auto;min-width:auto; 來卸除 hasLayout ,特別須注意的是 auto 值並非 w3c 標準,所以沒有把它列在上述卸除規則。

思考 - hasLayoutcss hacks 拯救 ie bugs

本篇一開始就提到,為物件指定 hasLayout 性質就可以修復很多 ie 令人噴飯的 css bugs (hasLayout 大部分可修復背景不正常及 position 特性位移等問題) ,有幾種目前公認穩定又好的方式,但是有時必須搭配 CSS hacks ,才可以在不同瀏覽器正常地呈現,而如果需要通過 W3C validation ,用到非 w3c 標準語法時就需要運用 Conditional Comments 把語法隔離起來。

xhtml
<div id="main" class="hasLayout">
 <h2>早梅 張謂</h2>
 <p>一樹寒梅白玉條,迥臨村路傍溪橋。不知近水花先發,疑是經冬雪未銷。</p>
</div>
css
.hasLayout {min-height:0;} /* ie 7 hasLayout 生效 */
* html .hasLayout {height:0;} /* hack ie 6 hasLayout 生效 */

上面 css 語法例子符合 w3c 標準,是很穩定的好方法,只是語法感覺有點冗長。 min-height:0; 本來就是預設值,加了此項其實是多餘的,所以對任何瀏覽器不會有影響,也就不需要用到 hacks ;而 min-height:0;ie 7 可驅使 hasLayout 生效,難纏的 ie bugs 也就隨之解決了。但是, height:0; 在不同瀏覽器上呈現有很大差異,所以就必須採取 css hacks 的技巧。 ie 7 與 ie 6 的 bugs 未必會在同一個物件同樣發生,所以,上述語法並沒有要求一定兩項條件都要同時存在,比較常出現 bugs 會是在 ie 6 ,可以視狀況加入其中一項或兩項囉。另外需要提醒的是,依據規則此方法在「文字層級」物件沒有作用。

承上 xhtml 例,再看另一種 css hasLayout 作法。

css
#main {zoom:1;}

zoom 指定 hasLayout 算是精簡的好方法, ie 5.5 以後版本就有支援。 zoom:1; 維持物件原來大小不作任何改變,但可驅使 hasLayout 有效,而且不論區塊層級或行內元素都有作用;非 ie 瀏覽器尚未支援 zoom 特性,所以完全不受影響,也就不需要用到 hacks 。唯一的小問題只是 zoom 並未納入 w3c 標準。

再看不同的例子。

xhtml
<div id="nav">
<ul>
 <li><a href="#">王維-陽關曲</a></li>
 <li><a href="#">張謂-早梅</a></li>
 <li><a href="#">杜甫-客至</a></li>
</ul>
</div>
css
#nav li a {display:inline-block;} /* hasLayout 生效 */
#nav li a {display:block;}

此例在版面設計常會遇到,因設計需要必須將行內元素 a 轉換成區塊層級呈現 (改變物件的 display 特性) ,很明顯地,加了 display:inline-block; 這項其實是多餘的,因為元素 a 還是會依照其後定義的 dislpay:block; 呈現,所以任何瀏覽器的呈現也不會有差異;而 display:inline-block; 驅使 hasLayout 生效, ie bugs 也就隨之解決了。這個方式 ie 5.5 以後版本就有支援,完全符合 w3c 標準,精簡且不需要用到 css hacks ,適當地運用也是一個很好的技巧。

最後叮嚀,不要想偷懶企圖使用像 * {zoom:1;} 的方式一次指定所有物件,發生問題的時候恐怕沒人救得了你;指定 hasLayout 性質的方式算是不少了,學習在不同情況下,針對有問題的物件變換最恰當的語法來修復 ie bugs ,才是網頁設計者應有的態度。

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

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

Pseudo-elements ::before, ::after 範例

  • 說明:以特別的 CSS selectors (指標) 語法,指向 html 元素 (elements, 如 p, h1, div 等) 裡沒有實際元素名稱或原來不存在的內容,並且使其被視為一個新的元素,稱之為擬元素 (pseudo-elements) 。在原有 selectors 加上 ::before::after擬元素表示法,如 #main::before ,將會指向該元素的內容最前或最後,並可在該處加入新的字元,而且新加的字元被視為新的元素,也可以賦予各種設計風格 (styles)。
  • 適合:有 htmlcss 語法基礎概念者。
  • 難度:等級2
  • 更新:
  • 支援: firefox, opera, safari, google chrome, ie8 。(至更新時)
xhtml
<strong class="amount">700</strong>
css
.amount::before {content:"$ ";}
.amount::after {content:" 萬元";}
原來只有 700 ,但加了 css 以後呈現會是
$ 700 萬元

思考 - ::before, ::after Pseudo-element Selectors 使用原則

::CSS3 擬元素的標準表示法,主要是為了與 :擬類別 (Pseudo-classes) 作區分,有別於原來 css2 兩者同樣使用 : 表示,目前較先進瀏覽器 (firefox, opera, safari, …) 均有支援。

::before 搭配 contnet 特性 (property) 雙引號內所指示的字元,可在 selectors 指定的元素最前加入該字串 (包括空格,如上例的 "$ "), css 因而將此字串視為一個元素,所以可以賦予該字串各種設計風格; ::after 一樣用法,不同的只是加在最後。可以把上例想像成加了兩個實際的元素,如:

xhtml
<strong class="amount"><span>$ </span>700<span> 萬元</span></strong>

另加一下 css 看看變化,

css
.amount {color:red;}

這樣會是整個 $ 700 萬元 都變成紅字,因為 ::before, ::after 所加入的字串擬元素,仍屬於 .amount 元素的內容,所以依據繼承性擬元素 $, 萬元 也都是紅字了。稍微改變一下 css 看看:

css
.amount::before {content:"$ "; color:blue;}
.amount::after {content:" 萬元"; color:blue;}

這樣只有擬元素變成藍字,結果會像 $ 700 萬元,先前定義的紅字還是存在。 ::before, ::after 沒有限制兩個同時都要指定,也可以只指定一個前或一個後。

需要注意的是,以 ::before, ::after 配合 content 所產生的擬元素字串,會視為行內層級元素 (inline emements),也就是文字層級 (text-level) 。

至於 content 特性還有更有用的字串加入方式,由於撰文時大多瀏覽器支援不甚完全,以後再作討論,有興趣可先參考 W3C The content Property 說明。

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

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

Conditional Comments [if IE] : ie 專用 (ie only) 條件式 html 註解的語法

  • 說明: ie 專用語法 (ie only) 。運用 html 註解形式 <!-- -->,在註解間加入特殊的語法,可使 ie 將該註解內容反視為有效語法,甚至可自動區分不同版本 ie 來解讀。而非 ie 瀏覽器 (firefox, opera, safari, google chrome …) 一律視其為註解,所以同時也有了區隔不同瀏覽器的功能,有點像是 html hacksie5 就已開始支援。
  • 適合:有設計網頁及撰寫 html 語法經驗者。
  • 難度:等級3
  • 更新:
<!--[if IE]>內容<![endif]-->
內容只有 ie 會顯現。
<!--[if IE 6]>內容<![endif]-->
內容只有 ie6 會顯現。
<!--[if lt IE 7]>內容<![endif]-->
內容只在比 ie7 更舊的版本會顯現。 [參考說明]
<!--[if gte IE 8]>內容<![endif]-->
內容只有 ie8 及其較新版本會顯現。 [參考說明]
<!--[if !IE]>-->內容<!--<![endif]-->
內容除 ie 以外都會顯現。 [參考說明]
<!--[if !(IE 6)]>內容<![endif]-->
內容除 ie6 以外的 ie 都會顯現。 [參考說明]
<!--[if (gte IE 6)&(lt IE 8)]>內容<![endif]-->
內容只從 ie6 以後及 ie8 之前版本會顯現。 [參考說明]
<!--[if (IE 7)|(IE 6)]>內容<![endif]-->
內容只有 ie7 及 ie6 會顯現。 [參考說明]
<!--[if gte IE 7]><!-->內容<!--<![endif]-->
內容在 ie7 及其較新版本,以及 ie 以外都會顯現。 [參考說明]

藍色部分 <!----> 為標準 html 註解的起始或結尾;除此之外,紅色部分即為 ie 能辨識的特殊語法。所以,只有 ie 會依據紅字所表示的條件來判斷呈現與否,而其它瀏覽器依標準一律當成是註解。

語法中空格不能任意省去,尤其注意 IE 之後,版本編號前的空格。除 IE 必須大寫,其餘英文字母都是小寫。註解的結尾語法都是 <![endif]-->

思考 - 條件式註解的應用

運用不同條件可在不同版本呈現的原理,我們可以做出提供使用者,類似瀏覽器版本線上偵測的範例 :

xhtml 語法
<!--[if IE]>
 <p>您正在使用的瀏覽器為 ie 。</p>
<![endif]-->
<!--[if IE 6]>
 <p>您正在使用的瀏覽器為 ie6 。</p>
<![endif]-->
<!--[if IE 7]>
 <p>您正在使用的瀏覽器為 ie7 。</p>
<![endif]-->
<!--[if lt IE 7]>
 <p>您正在使用的瀏覽器為比 ie7 較舊的版本。</p>
<![endif]-->
<!--[if gte IE 8]>
 <p>您正在使用的瀏覽器為 ie8 或比 ie8 更新的版本。</p>
<![endif]-->
<!--[if !IE]>-->
 <p>您正在使用的瀏覽器不是 ie 。</p>
<!--<![endif]-->
<!--[if !(IE 6)]>
 <p>您正在使用的瀏覽器為 ie ,但不是 ie6 。</p>
<![endif]-->
<!--[if (gte IE 5.5)&(lt IE 7)]>
 <p>您正在使用的瀏覽器為 ie5.5 或 ie6 。</p>
<![endif]-->
<!--[if (IE 7)|(IE 6)]>
 <p>您正在使用的瀏覽器為 ie7 或 ie6 。</p>
<![endif]-->
<!--[if gte IE 7]><!-->
 <p>您正在使用的瀏覽器為 ie7 或比 ie7 更新的版本,或不是使用 ie 。</p>
<!--<![endif]-->
上面的語法實際呈現如下,請使用不同瀏覽器測試。

您正在使用的瀏覽器不是 ie

您正在使用的瀏覽器為 ie7 或比 ie7 更新的版本,或不是使用 ie

ie Conditional Comments 幾乎可以包圍任何 html 內容,包括整個元素 (elements) 或單獨的標籤 (tags) ;這屬於 html 語法,只適用在 html 語法內,出現在其它如 css 語法裡或 javascript 程式裡是會錯誤的。有時候我們因某些狀況不得不使用 ie 自創專有的語法,又必須符合 w3c 標準語法規範,或是需要避開 ie 的錯誤,又為了避免與其它瀏覽器發生衝突,條件式註解就成了有用的技巧。

條件註解當作 css hacks

僅供 ie6 及其較舊版套用的樣式清單檔
<!--[if lte IE 6]>
 <link href="style_ie6.css" rel="stylesheet" type="text/css" />
<![endif]-->

條件註解javascript 在指定的瀏覽器執行

僅供 ie 執行的 javascript 程式檔
<!--[if IE]>
 <script src="script_ie.js" type="text/javascript"></script>
<![endif]-->

註解裡的運算子 (operators) : lt, lte, gt, gte

語法中除了 if, IE 比較容易體會含意外,其餘看似難懂的符號,列出來解釋一下就容易了。

  • lt : lower than ,比某一版本更舊的版本,如 [if lt IE 7]
  • lte : lower than or equal to ,某一版本及其更舊的版本,如 [if lte IE 6]
  • gt : greater than ,比某一版本更新的版本,如 [if gt IE 6]
  • gte : greater than or equal to ,某一版本及其更新的版本,如 [if gte IE 8]
  • ! : 「非」、「排除」、「反向」的意思,可加在版本、運算子、或子運算式 ( ) 前,如 [if !IE] ,指定 ie 以外有效。
  • ( ) : 可將基本的條件加入子運算式 (subexpression) 處理更複雜的條件,如 [if !(IE 6)] ,指定除 ie6 以外的 ie 有效。。
  • & : 符合由 & 連接的全部子運算式的條件,如 [if (gt IE 5.0)&(lt IE 7)] ,指定 ie5 之後, ie7 之前有效。
  • | : 符合由 | 連接的任一個子運算式的條件,如 [if (IE 5.5)|(IE 6)] ,指定 ie5.5 或是 ie6 有效。

所以, [if lte IE 6][if lt IE 7] 同樣指的都是 ie6 及其更舊版本,而 [if gt IE 6][if gte IE 7] 同指 ie7 及其較新版本。

實際上,常用的運算子應該只有前面五項,所以沒有特別需求的話,不需要浪費太多時間鑽研每一項的用法囉!

稍作變化才能正確用在 ie 以外瀏覽器

在前面語法中,關於 ie 以外瀏覽器顯現的作法,加了一點東西,這是將 ie 專用註解語法 (紅色部分) ,再加註解標記,變成前後兩部分 html 標準註解 (注意藍色部分) ,才可以讓內容不再是註解;而 ie 仍舊以原來特殊語法判斷,不會理會另外加的符號,如此既能區分瀏覽器,又不會違反 w3c 標準語法。另外需要注意的是,如果同時也要讓某些 ie 顯現 (如最後一項) ,就必須動點手腳,如 [if gte IE 7]><!--> 中多加了 <! (綠色) ,只是為了避免 ie 會把接下去的 --> 顯示出來。

類似運用註解的方法在許多應用軟體也常見到,例如 Adobe Dreamweaver 裡的範本 (templates) 標籤、圖庫 (library) 標籤,也都是運用註解標註的方式讓特定的應用軟體來辨識,所以瀏覽器只會把它們當成註解而已,多留意看看就會發現其中的奧妙了。

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

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

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) 人氣()

«12