當人們剛接觸佈局的時候都比較傾向於使用定位的方式。因為定位的概念看起來好像比較容易掌握。表面上你確切地指定了一個塊元素所處的位置那麼它就會坐落在那裡。可是定位比你剛看到的時候稍微複雜一點。對於定位來說,有一些東西會絆倒新手,所以在它成為你的慣用技巧之前你需要掌握它們。
一旦你更深入地了解了它是如何運作的,你就能夠做出一些更棒的事情來。
CSS盒模型和定位的類型
# 為了搞清楚定位首先你得了解CSS盒模型。在上一句的連結是我寫在InstantShift 中的一篇關於盒子模型的文章。我在那篇文章做了詳細的講解並會在這篇文章中做一個快速的總結。
在CSS中,每個元素都由一個矩形盒子所包含。每一個盒子都會具有一個內容區,內容區被一個內邊距所包裹,內邊距外是盒子的邊框,並且在邊框之外會有一個外邊距用於與其他盒子分隔開來。這些你可以從下面這張圖片看到。
定位模式規定了一個盒子在整體的佈局上應該處於什麼位置以及對周圍的盒子會有什麼影響。定位模式包括了常規文件流,浮動,和幾種類型的 position 定位的元素。
CSS position 屬性可以取5種值:
position: absolute position: relative position: fixed position: static position: inherit
我會在下面對前三個值進行詳細的闡述並簡單地講解一下最後兩個值。
static 是 position 預設的屬性值。任何應用了 position:static 的元素都處於常規文件流中。它處於什麼位置以及它如何影響週邊的元素都是由盒子模型決定的。
一個 static 定位的元素會忽略所有 top,right,bottom,left 以及 z-index 屬性所宣告的值。為了讓你的元素能使用任何的這些屬性,你需要先為它的position 屬性應用這三個值的其中之一: absolute,relative,fixed
position 值為inherit 的元素和其他所有屬性的繼承值一樣,元素只是簡單地應用了與父元素一樣的position 值。
絕對定位(Absolute Positioning)
# 絕對定位的元素會完全地從常規文件流中脫離。對於包圍它的元素而言,它會將該絕對定位元素視為不存在。就好像 display 屬性被設為 none 一樣。如果你想要保持它所佔有的位置而不被其他元素所填充,那麼你需要使用其他的定位方式。
你可以透過 top, right, bottom, 和 left 四個屬性來設定絕對定位元素的位置。但你通常只會設定它們其中的兩個,top 或 bottom,以及 left 或 right。預設地它們的值都為 auto。
弄清楚絕對定位的關鍵是知道它的起點在哪裡。如果 top 被設定為20px那麼你要知道這20px是從哪裡開始計算的。
一個絕對定位的元素的起點位置是相對於它的第一個 position 值不為 static 的父元素而言的。如果在它的父元素鏈上沒有滿足條件的父元素,那麼絕對定位元素則會相對於文件視窗來進行定位。哈!
關於「相對」這個概念你或許有點迷惑,尤其是還有一個叫相對定位的東西,這是我們還沒講到的。
當你在一個元素的樣式上設定 position:absolute 表示需要考慮父元素,並且如果父元素的 position 值不為 static ,那麼絕對定位元素的起點為父元素的左上角位置。
如果父元素沒有套用除了 static 以外的 position 定位,那麼它會檢查父元素的父元素是否有應用非 static 定位。如果該元素應用了定位,那麼它的左上角就會成為絕對元素的起點位置。如果沒有則會繼續向上遍歷DOM直到找到一個定位元素或尋找失敗以到達最外層的瀏覽器視窗。
相對定位(Relative Positioning)
相對定位的元素也是根據 top, right, bottom, 和 left 四個屬性來決定自己的位置的。但只是相對於它們原來所處於的位置進行移動。在某種意義上來說,為元素設定相對定位和為元素添加 margin 有點相似,但也有一個重要的區別。差異就是圍繞在相對定位元素附近的元素會忽略相對定位元素的移動。
我们可以把它看做是一张图片的重像从真实的图片的位置开始进行了一点移动。它原始图片所占据的位置仍然保留,但我们已经没法再看到它,只能看到它的重像。这样就让元素之间可以进行位置的重叠,因为相对定位元素能够移动到其他元素所占据的空间中。
相对定位元素离开了正常文档流,但仍然影响着围绕着它的元素。那些元素表现地就好像这个相对定位元素仍然在正常文档流当中。
我们无需再追问这个相对的位置是在哪里。因为这个相对位置很显然是正常的文档流。相对定位有点儿像为元素添加了 margin ,对相邻元素来说却像是什么都没发生过。但实际上并没有增加任何的 margin 。
固定定位(Fixed Positioning)
固定定位的行为类似于绝对定位,但也有一些不同的地方。
首先,固定定位总是相对于浏览器窗口来进行定位的,并且通过哪些属性的 top, right, bottom, 和 left 属性来决定其位置。它抛弃了它的父元素,它就是定位中表现地有点儿反叛。
第二个不同点是其在名字上是继承的。固定定位的元素是固定的。它们并不随着页面的滚动而移动。你可以告诉元素它所处的位置并永远不再移动。噢~好像还挺乖巧的。
在某种意义上说固定定位元素有点儿类似固定的背景图片,只不过它的外层容器块总是浏览器窗口罢了。如果你在 body 中设置一个背景图片那么它与一个固定定位的元素的行为时非常像的,只不过在位置上的精度会略少一些。
背景图片也不能改变其在第三个维度的大小,也因而带来了 z-index 属性。
打破了平面的 Z-Index
这个页面是一个二维平面。它具有宽度和高度。我们活在一个用 z-index 作为其深度的三维的世界当中。这个额外的维度能够穿越一个平面。
由上图可知,高的 z-index 位于低的 z-index 的上面并朝页面的上方运动。相反地,一个低的 z-index 在高的 z-index 的下面并朝页面下方运动。
没有的 z-index 的话,定位元素会有点儿麻烦。因为 z-index 能让一个定位元素位于另一个元素的上方或者下方,这或许能让你做出点创造性的东西。所有的元素的默认的 z-index 值都为0,并且我们可以对 z-index 使用负值。
z-index 实际上比我在这里描述的要更加地复杂,但细节写在了另一篇文章里。现在只需要记住这个额外维度的基本概念以及它的堆叠顺序,另外还要记住只有定位元素才能应用 z-index属性。
定位的问题
对于定位元素来说由几个比较常见的问题,都值得我们好好了解。
1.你不能在同一个属性当中应用定位属性和浮动。因为对使用什么样的定位方案来说两者的指令时相冲突的。如果你把两个属性都添加到一个相同的元素上,那么就期望在CSS中较后的那个属性时你想要使用的吧。
2.Margin 不会在绝对元素上折叠。假设你具有一个 margin-bottom 为20px的段落。在段落后面是一个具有30px的 margin-top 的图片。那么段落和图片之间的空间不会是50px(20px+30px)而是30px(30px > 20px)。这就是所谓的 margin-collapse,两个 margin 会合并(折叠)成一个 margin。
绝对定位元素不会像那样进行 margin 的折叠。这会使它们跟预期的不一样。
3.IE在 Z-index 上有一些BUG。在IE 6中 select 元素总是处于堆叠层级的最上方而不管它的 z-index 和其他元素的 z-index 是多少。
IE 6和IE 7在堆叠层级上又有另外一个问题。IE 6由最外层的定位元素的层级来决定哪一组的元素处于层级的最上面,而不是每一个单独的元素自身的层级决定。
<p style="z-index: "> <p style="z-index: 1"></p> </p> <img style="z-index: " />
对上面这段结构,你会预料段落元素处于堆叠层级的最上方。因为它具有最大的 z-index 值。但在IE 6和IE 7中,图片为处于段落的上方。因为 img 具有比 p 更加高的 z-index 层级。因此它会位于所有 p 的子元素的上方。
总结
一個元素上所設定的位置屬性會根據其中的一種CSS定位模式來運作。你可以為定位元素設定 absolute, relative, fixed, static (預設), 和 inherit 中的其中一個值。
定位模式和CSS定位元素,定義了一個盒子在佈局中應該處於什麼位置以及圍繞它的元素會受到定位元素帶來的影響。
z-index 屬性只能應用在定位元素上。它為頁面增加了第三個維度並設定了元素的層級上的順序。
定位屬性看起來好像很好理解,但它的運作與它在表面所看到的有點不一樣。你可能會覺得的是相對定位更類似絕對定位。當在做佈局設計的時候你通常會想要使用浮動並在指定的元素上應用定位來打破佈局。
更多剖析CSS Position定位相關文章請關注PHP中文網!