在這之前,請先拜讀:
開始之前,請先默念:
本文第一心法:IE6 sucks!
CSS 打從 1.0 到現在的 2.1,目前只有在 IE8 才是完全依照 CSS 2.1 的標準在走。這當然對於網頁設計的 ART 來說是很討人厭的事情。為什麼這麼說?這就像是在多年以前,要寫 DHTML 時,IE 與 Netscape 所使用的語法完全不同的狀況是一樣的,而 CSS 的應用就更糟糕,語法一模一樣,結果卻全然不同。這些差異其實很讓人傷腦筋,畢竟在全球的使用者中,IE 還是大宗,更恐怖的是 IE6 則是在這些 IE 使用者中的 90% 以上。
差在哪?就差在好的瀏覽器讓 ART 上天堂,IE6 只能讓 ART 住公司(沒有誤)。在 CSS 的標準規則裡面,最容易出現誤差的設定有下列幾項:
- padding
- margin
- position
- float
- clear
- line-height
- height
- width
眼尖的人應該會發現,我並沒有把選擇器(Selector)給列入,因為 IE6 sucks! 的關係,IE 對於選擇器能夠完全正常,也只有 IE8 而已,所以在這裡先不討論選擇器的問題。我們就針對上述的這些設定來研究瀏覽器之間的差異。
較常使用到上述設定的,大多為 Box model,這裡稍微說明一下(W3C 的圖不可愛):
以上就是 Box 元件的性質,包含了外邊留白(margin
)、邊框(border
)與內邊留白(padding
),定位包含了上、右、下、左(top
, right
, bottom
, left
)與左上、右上、左下、右下(top left
, top right
, bottom left
, bottom righ
t)。內容(content
)與邊框(border
)都是屬於可見的屬性設定,留白(margin
, padding
)就屬透明屬性設定(意即不能使用顏色設定)。
眼花了嗎?沒關係,先來默念一下:
本文第二心法:200 + 800 > 1000
請不要懷疑,這個問題在接觸了 Box 元件之後一定會遇到,本心法可以回朔至第一心法,基本上是個無限迴圈。為什麼會發生這種狀況呢?其主要的原因在於各大瀏覽器對於定位、寬度以及留白都有不同的認知,而其最大的主因,請在默念一次本文第一心法:IE6 sucks!,沒有錯,你會在這篇文章中看見很多 IE6 sucks!。當然,這種問題並不單純只是出現在 IE 而已,如果對於 Box 元件屬性不熟悉,到哪種平台的瀏覽器你都會覺得奇怪。
請看圖說故事:
當然,這個並不是什麼鐵則。這種情況在常用 TABLEs 的人應該常遇到。瀏覽器在讀取 HTML 的時候,大多會將這些 Box 元件的留白給個預設值(像是 body 就會給個 10px 之類的),好意是,不要讓你的 Box 元件全部都黏在一起,但是另一個影響就是,200 + 800 > 1000
這種狀況就會浮現。而,為了避免這種情況,我們時常在許多 CSS 的設定檔案裡面看到這種設定:
* {
margin: 0;
padding: 0;
border: 0;
}
這是一個大家很容易遺忘的一個狀況:
真實顯示尺寸 = 設定尺寸 + 留白 + 邊框 (+ 行高)
所以,當我們使用 Box 元件進行排版時,就必須要注意 Box 元件本身的設定:
- 寬度(width)
- 高度(height)
- 內外留白(margin, padding)
- 邊框(border)
- 行高(line-height)
- 是否使用浮動(float)
- 是否使用定位(position)
前四項,我想上面的圖片都已經解釋的很清楚,至於行高(line-height),請看圖:
行高(line-height
)其實是個很奇妙的設定,若是沒有強迫指定的話,他是會跟著 font
設定做 1:1 的比例顯示。麗如說,你的字型大小設定為 12pt
,那麼你的行高就是 12pt
的系統指定行高,至於這個系統指定行高是多少,一般來說會多個 2px
上下,這個差距則是要看使用者端的顯示設定而有些微的差距。
上圖所描述的狀況就是,當行高(line-height
)設定大於 Box 元件本身的高度(height
)設定的時候,會將整個 Box 元件給撐開,造成了莫名的上邊內部留白狀況(padding-top
)。這種因為行高產生的留白狀況,最常出現的是在使用 TABLEs 來切圖,而使用不同的 DTD 時,整個 TABLEs 中的 TR 與 TD 標籤就會裂開來,造成了原本使用 TABLEs 縫合的圖片,全部像是拼圖一樣被切開。
接著,我們來談談浮動(float
)與定位(position
),請默念法則:
本文第三心法:愛惜它(float
)善用它(clear
)忽略它(position
)
浮動與定位是在 CSS 中最常被拿來排版的兩個屬性。個人覺得,浮動要比定位來的更好用一點點。在這裡,希望你有一些基礎的 Layer(層)的概念,這樣浮動與定位對你來說應該就不難理解。再提到這個區塊之前,還需要任是一個屬性,叫做 z-index
,你可以把它想做是三度空間裡面的 Z 軸,也就是除了寬度、高度之外的第三個"深度"。這個深度的應用在浮動或定位元件裡面非常常見,是用以指定 Box 元件在顯示的"前後順序"的依據。一般來說,這樣的前後順序都是依照 DOM Tree 的排列"由上而下"的順序做為預設的指定順序,而,z-index
則可以修改這樣的順序。
然而,在 DHTML 正夯的時候,定位(position
)這個屬性幾乎無所不在,那我現在為什麼要說忽略它呢?其實原因不難,定位這樣的屬性較多應用於複雜,且不易切割的版型上,加上現在瀏覽器顯示不一的狀況,定位這個屬性的使用時機與使用方向就變的比較模糊。且,定位屬性設定中,除了常見的 absolute
與 relative
較為常用外,像是 static
(預設值),fixed
與 inherit
就較少人使用。而,absolute
與 relative
這兩個屬性值,會依照 Box 元件的從屬關係而有不同的反應(結果)。
簡單的說,Box 元件在使用 position
時,會因為元件本身的 DOM 結構與 z-index
的設定而有所不同,這不僅僅只會發生在 DOM 或是 CSS 設定上,也會因為瀏覽器的不同而有產生不一樣的結果。
反觀浮動(float
)屬性,就單純的多,它只有四種屬性值:left
, right
, none
(預設值)與 inherit
。為什麼說它單純,從屬性值來看,我們可以很簡單的理解,它只能左右浮動,或是依據使用者給予該屬性的預設值(inherit
),或是根本不浮動(none
)。這樣的設定我們可以很單純的將某些需要排版的物件,利用浮動與留白(padding
, margin
),甚至是尺寸(width
, height
),來決定我們的浮動物件在畫面上的位置。
這樣跟定位有什麼不同?不同的地方大致上有:
- 浮動與解析度無關,定位物件是以瀏覽器
document
的尺寸為基準。 - 浮動物件只影響同樣為浮動的物件,類似定位物件中的
relative
設置,但relative
設置會因為其他 Box 物件的位置而有所不同。 - 推齊(
clear
)屬性設定對定位(position
)屬性設定無效果,僅對浮動(float
)有效。 - 定位物件無論 DOM 結構如何,皆會互相影響,包含父元件內的子成員也會對父元件層級的成員造成影響,浮動物件則依照 DOM 結構而定,不會越級干擾。
- **兩者混用會造成 DOM 混亂。
我們來看看真實範例(本範例不包含定位與浮動混用狀況):
<div id="container">
<h1>Container</h1>
</div>
<div id="item1">
<h1>Item 1</h1>
</div>
<div id="item2">
<h1>Item 2</h1>
</div>
<!-- "clear" cannot apply in "position" CSS setting. -->
<br class="clear" />
<div id="item3">
<h1>Item 3</h1>
</div>
<div id="item4">
<h1>Item 4</h1>
</div>
<div id="item5">
<h1>Item 5</h1>
</div>
<!-- "clear" can apply in "float" CSS setting. -->
<br class="clear" />
<div id="item6">
<h1>Item 6</h1>
<div id="item7">
<h1>Item 7</h1>
</div>
</div>
<!-- "clear" can apply in "float" CSS setting. -->
<br class="clear" />
<div id="item8">
<h1>Item 8</h1>
<div id="item9">
<h1>Item 9</h1>
</div>
</div>
<div id="item10">
<h1>Item 10</h1>
</div>
#container {
width: 280px;
height: 280px;
padding: 10px 10px;
margin: 0;
border: 1px solid #ff3333;
background-color: #efefef;
}
#item1 {
position: relative;
top: -200px;
left: 200px;
width: 280px;
height: 280px;
padding: 10px 10px;
margin: 0;
border: 1px solid #ff3333;
background-color: #efefef;
filter: alpha(opacity=50);
-moz-opacity: 0.5;
}
#item2 {
position: relative;
top: -400px;
left: 400px;
width: 280px;
height: 280px;
padding: 10px 10px;
margin: 0;
border: 1px solid #ff3333;
background-color: #efefef;
filter: alpha(opacity=50);
-moz-opacity: 0.5;
}
#item3 {
position: relative;
top: 0px;
left: 0px;
width: 280px;
height: 280px;
padding: 10px 10px;
margin: 0;
border: 1px solid #ff3333;
background-color: #efefef;
}
#item4 {
float: right;
width: 280px;
height: 280px;
padding: 10px 10px;
margin: 0;
border: 1px solid #ff3333;
background-color: #efefef;
}
#item5 {
float: right;
width: 280px;
height: 280px;
padding: 10px 10px;
margin: -800px 200px 0px 0px;
border: 1px solid #ff3333;
background-color: #efefef;
}
#item6, #item8 {
width: 480px;
height: 480px;
padding: 10px 10px;
border: 1px solid #ff3333;
background-color: #efefef;
}
#item7 {
float: right;
width: 280px;
height: 280px;
padding: 10px 10px;
border: 1px solid #ff3333;
background-color: #efefef;
}
#item9, #item10 {
position: relative;
top: 100px;
left: 100px;
width: 280px;
height: 280px;
padding: 10px 10px;
border: 1px solid #ff3333;
background-color: #efefef;
}
由以上的範例,應該可以很清楚的分辨定位與浮動的不同。特別是在 Item 8, Item 9 與 Item 10 的關係,我已經把 Item 9 與 Item 10 的原始位置用圖示標記出來,**倘若拿掉那個粉紅色方塊,你能夠知道為什麼 Item 10 跟 Item 8 會有那一段莫名的空白嗎?**這就是子元件影響到父元件層級的一個例子,由於定位物件是針對整個 document.body 做為參考,所以對於 DOM 的結構規範是沒有作用的。另外,定位物件會因為解析度的關係而有不同的結果,所以你若是利用上述的範例所產生的畫面,可能跟我所看見的不同。
總結來說,定位元件並不是很適合拿來做版面的排版,當然這是個人的感想,在許多 CSS 免費樣版提供的平台中,還是有不少的 CSS 是使用定位的方式來設定版面。除非是做到良好的控制,否則對於會變動的內文樣式來說,浮動元件也許是比較適合拿來做排版。畢竟,配合浮動元件的另一個利器:推齊(clear
)也是很好很強大的。
不知道這樣,你能了解到推齊(clear
)的美好嗎?
最後,請默念一千遍:IE6 sucks!