使用CSS來定位頁面內層的位置,一直是比較難以掌握的事情,很多時候,往往被絕對定位的元素,總是以浏覽器的左上角為坐標原點,此時,如果浏覽器的大小改變,被定義的層就會偏離設計想要的位置,讓人很撓頭。
其實,要想控制好層的絕對定位,只要理解CSS中關於定位(position)的定義,一切就會變得輕松簡單。
CSS中關於定位(position)是這樣定義的:
定位(position)允許用戶精確定義元素框出現的相對位置,可以相對於它通常出現的位置,相對於其上級元素,相對於另一個元素,或者相對於浏覽器視窗本身。每個顯示元素都可以用定位的方法來描述,而其位置由此元素的包含塊來決定的。
包含塊(containing block)是格式編排發生的關聯場景,例如,一個加粗的元素的包含塊可以是該元素所出現的段落,如圖1所示。
在理解定位之前,首先,要先理解HTML文件的結構,例如有一個html文件內容如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>文檔結構</title>
</head>
<body>
<h1>CSS規則</h1>
<p>樣式表由一些<strong>樣式規則</strong>組成。</p>
<ul>
<li>選擇符
<ul>
<li>類選擇符</li>
<li>ID選擇符</li>
<li><em>包含</em>選擇符</li>
</ul>
</li>
<li>屬性</li>
<li>值</li>
</ul>
</ul>
</body>
</html>
此文檔對應的樹型結構,如圖2所示。
CSS大部分能力是基於元素的“父子”關系,在圖2的家族樹中,每個元素都是另一個元素的“父”或者“子”或者兩者都是。例如:body既是html的子元素,又是h1的父元素,而html就是h1的祖先,h1則是html的子孫。
Body是所有浏覽器能顯示的元素的祖先,而html是所有元素的祖先,也稱為“根元素”。
那為什麼定位了的元素還總是以浏覽器窗口的左上角為坐標呢?
因為並不是每個元素都能為其後輩元素生成一個包含塊。
建立包含塊的規則如下:
- “根元素”的包含塊(也叫初始包含塊)由用戶代理生成,在HTML中,根元素是HTML元素,盡管有的浏覽器會不正確地使用body元素。
- 對於那些未絕對定位的非根元素來說,元素的包含塊設置為最近的塊級祖先元素的內容區邊沿。
- 對那些使用絕對(absolute)作為定位(postition)的非根元素,包含塊設為最近的定位(postition)不是靜止(static)的祖先元素(任何類型)。有以下幾種情況:
- 如果祖先元素是塊級(block)元素,包含塊設為祖先元素的填充(padding)邊沿,也就是被邊框(border)約束的區域。
- 如果祖先元素是內聯(inline)元素,包含塊設為祖先元素的內容邊沿。
關於包含塊,最重要的是要記住它為所有後輩元素建立了一個格式編排的上下文。另一個重要方面是,元素可定位於它們的包含塊之外。
因此,絕對定位的元素往往以浏覽器可視區域的左上為坐標原點來進行定位了。
在CSS中可是使用position屬性來在不同的定位類型中選擇。
語法:
position : static | absolute | fixed | relative | inherit
其各參數含義是:
- static : 靜態(默認),無特殊定位。
- relative : 相對,對象不可層疊,但將依據left,right,top,bottom等屬性在正常文檔流中偏移位置
- absolute : 絕對,將對象從文檔流中拖出,使用left,right,top,bottom等屬性進行絕對定位。而其層疊通過z-index屬性定義。此時對象不具有邊距,但仍有補白和邊框。
- fixed : 懸浮,使元素固定在屏幕的某個位置,其包含塊是可視區域本身,因此它不隨滾動條的滾動而滾動。(IE5.5+不支持此屬性。)
- inherit : 這個值從其上級元素繼承得到。
示例:
div {...}{ position: absolute; bottom: 1in; left: 1in; right: 1in; top: 1in; }
div {...}{ position:relative; top:-3px; left:6px; }
既然了解了包含塊的概念,那麼對於相對定位和絕對定位的關系,就很好掌握了。
例如,現在需要把頁面內容整體居中,然後再將其中某些層絕對定位的話,那就要把最外面的層設置定位屬性。
<body>
<div id="box">
<div id="nav">
<p>每個顯示元素都可以用定位的方法來描述,而其位置由此元素的<strong>包含塊</strong>來決定的。</p>
</div>
</div>
</body>
此時,如果你要對nav絕對定位,則需設置css:
body {...}{
margin:0;
padding:0;
text-align:center;
}
#box{...}{
background:#ff0;
position:relative; /**//* 使box層成為其子孫元素的包含塊 */
width:500px;
height:200px;
margin:0 auto;
}
#nav {...}{
background:#ccc;
position:absolute; /**//* nav層將在box層的邊框范圍內絕對定位 */
top:20px;
left:40px;
width:200px;
}
其顯示效果如圖3所示。
因此,掌握了包含塊的概念,定位就變得不那麼困難了。
本文部分知識來源於:《CSS權威指南》