- 難度:

- 適合:有 html 及 css 語法撰寫基礎者。
- 說明: ie 專有用法 (ie only)。部分 ie 專有的特性 (property) ,如
filters and transitions ,有作用的必要條件就是指定 hasLayout 性質。 hasLayout 性質本來是微軟為了補救 ie 內部不完善所自創的,並非 w3c 標準,所以有時用起來覺得相當無厘頭。但神奇地, ie 衍生的網頁不正常呈現問題 (ie bugs),大多數竟可由指定 hasLayout 來解決。
- 更新:2008-02-18
為物件指定 hasLayout property
hasLayout "property" 和 css property 雖然英文名稱一樣,但實際上不太相同。 hasLayout 本身並非 css 特性的一種,所以沒辦法直接定義物件的 css 特性 hasLayout 的值 (value),而是間接以其它的 css 特性指定在物件上,使該物件符合 hasLayout ,所以我比較傾向稱它是 hasLayout 「性質」。
- 符合以下任一種 css 特性及值的定義方式,物件即是
hasLayout (有編置) :
-
- ie 7 增加了幾個新的指定方式:
-
認識 hasLayout 的 css 規則
上述規則有的看起來有點含糊,有的好像又很陌生,那要怎麼正確定義物件 hasLayout 呢?
height 或 width 特性只需要指定一個「具體值」 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-x 及 overflow-y 為 css3 的規則,撰文時僅 ie 及 firefox 支援。
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-height 與 min-width 的預設值是 0,所以縱使再定義為 min-height:0; (具體值),也無法卸除 hasLayout 。但是 ie 卻接受 min-height:auto; 或 min-width:auto; 來卸除 hasLayout ,特別須注意的是 auto 值並非 w3c 標準,所以沒有把它列在上述卸除規則。
- 參考資源
-
思考 - css 設計的構思與佈局
我們儘量以探討方式介紹,引導如何構思及擴展 css 設計,希望能激發更多設計想法為主,避免陷入步驟式或教條式的悲慘學習模式。
開始:定義一些基本的 css 設計
最外圍的
.TreeMenu指定寬度 (width) 、背景顏色 (background)、邊線 (border) , 而h1指定字體大小 (font) ,a去掉底線,ul,h1去除周圍距離 (padding,margin) 等等。cssline-height(行高) 是設計的主要概念視覺性的瀏覽器通常會預先賦予每行「大於一個字」的行高 (
line-height) ,為了避免不同瀏覽器間產生的差異,以及後面設計 css 時有所依據,先將整個選單內line-height定義為「字高度」的倍數,例中為 1.1 倍,看起來行距應該會較原來更緊一點。由於line-height特性 (property) 有繼承性 (inheritance) ,所以只需要定義一次在.TreeMenu或.section就可以;這裡也順便為分類標題h1加背景色修飾一下。css定義 (紅字)我們只以倍數定義行高,也沒有指定字體的尺寸 (
font-size),如此是為了使全部的設計,單純地以字高 (em) 的倍數來計算,不用去管字體到底幾個像素 (pixel) 大,或者一行有多少像素高。想指定font-size當然可以,不過行高最好還是以倍數的方式指定,設計時才不至於太難計算;這只是建議囉,全部都用像素為單位也沒問題,計算清楚,小腦袋瓜別爆掉就好。產生樹狀的垂直線條
在
ul左側加上線條,當做樹狀結構的垂直線,並且左邊空出一點距離,讓子選項內容li看起來向內縮排。這個距離應該是要對應分類標題h1來設計,我們指定了向內縮半個字 (0.5em),所以線看起來像是由標題第一個字中間向下延伸;標題最前面如果變成小圖示 (icons) ,那就以圖示寬度的一半去定義縮排距離也可以。這裡應該以margin來指定內縮距離,因為我們必須讓垂直線緊貼著li。線條寬度沒有使用em定義,是因為1px寬幾乎沒什麼影響,但是如果需要設計較粗的線,單位最好一致。ul增加css定義 (紅字)我們沒有特別指定線條
border的顏色,將會與該區域字的顏色相同,如果想另外定義顏色,可以像這樣,線條要改成實線也可以,
dotted → solid,當然其它形式的線條也可有更多變化。產生樹狀的水平連接線條
在子選項
li下方加上線條,當做樹狀結構子選項的橫連接線。這裡也讓li的內容a向內縮排,不過,不同於前面,我們必須保持每個li下方的線與左側ul的線緊緊相接,所以在li指定padding,僅讓內容a向內縮,但li本身沒有縮排。li的css定義border也沒有特別指定顏色,這樣可以對應前面ul的border顏色,如果想另外定義顏色,方法同前。css
position:relative;讓a向下位移 (offset)css
position:relative;主要的特點就是,元素可以由本身的 Box 位移,並且保留其它元素原來的排版。利用這個特點,只要讓a向下位移半行,而li會維持原來的位置及下方的橫線,a的中間就會剛好壓在li的線上。前面已經指定line-height:1.1;(1.1倍的字高),所以半行就是0.55em,太棒了,只有a向下移,所有a以外的東西都不會動。a增加css定義 (紅字)由於水平線條只有
1px厚度,對整個位置並無影響,可以不需考量;但是如果指定了較粗的線條,就需要顧慮到線條的厚度會佔掉空間,向下位移的距離應該多加半個線的厚度,這也是為什麼前面有提醒要注意單位一致的原因,如果線的單位是px,而行高是em,那還真有點難算。背景顏色蓋掉重疊的線
明顯地,現在面臨兩個問題:一、字的背面不應該有線。二、因為
a的向下位移,造成與下一個分類重疊。第二個問題稍後再討論。第一個問題比較容易處理,我們為a指定背景色就可以蓋住li的橫線了,由於a本身為行內層級元素 (inline-level elements) ,所以背景色只會在有字的區域呈現。如果a不想有背景顏色,只要指定與.TreeMenu相同的背景色,a看起來就像沒有背景色的樣子。a增加css定義 (紅字)如果想讓字之後的整條線都蓋掉,只要把
a轉換成區塊層級 (block-level) 呈現即可。a增加css定義 (紅字)此時會看到子選項內容
a之間有1px的間隔,這是因為a的實際高度本來就比li少1px高 (li比a多了線條的高度)。增加距離避免重疊,就算完成了。
只要在分類間加一點距離,重疊的問題就解決了,為
.section下方加上padding應是較恰當的方式。為了分類裡面的上下距離看起來一樣 ([上古神話]上方與[章回小說]下方) ,我們指定了padding-bottom:1.1em;,與行高相等的距離。.section增加css定義 (紅字)換成在
ul下方增加距離也可以,不過,只能以margin來定義,因為padding會使左側的線跟著向下延長,就不會與最後一個li的橫線緊接了。目前應該已經算是完成囉,只剩下修飾更好而已。
hasLayout處理 ie bugsie 7 或 ie 6 ,在
ul或a可能會發生高度失準或背景圖片移位的問題,解決這類的 bugs 常用的方式是 hasLayout property 。由於目前在 ie 8 都還正常,為了清楚區隔,我們最好運用 css hacks 技巧。css定義a還是有高度或不正常間隙問題在子選項前加小圖示,並且做最後修飾
以小圖示作為
a的背景,並且指定左邊padding距離,讓a的內容文字向內縮排,才不會與小圖示重疊。例中的小球圖示 (ic008.png) 寬度10px,我們指定它的位置在a的最左側並且上下居中,這樣會讓小球剛好緊接在li的線後,然後左側padding距離為15px,讓字不要與圖看起來太緊鄰。另外,把a的背景顏色指定成與.TreeMenu相同。我們也在
a及標題h1上下加了一點padding距離,讓字看起來不會與邊緣太緊鄰。不過,a上下各增加了0.25em,表示整行的高度也增加了,所以,向下位移的top定義也需要對等增加0.25em的距離 (0.55 + 0.25 = 0.8em) ;而.section下方的padding距離也應該增加為1.6em(1.1em + 0.25em + 0.25em) 。css設計前面提到由於
li的下方線條使a之間會有1px間距,只需要在a或li指定margin-bottom:-1px;(綠字),就會使li之間有1px重疊,a之間就沒有間距了,不過, ie 7, ie 6 最後一個li的線會看不見,修正方式也加在 hacks 裡了 (綠字) ,有興趣可以自行試試。