一、問題來源
自己寫輪播圖切換的時候前一幅圖滑動時後邊出現空白直到前一幅圖全部滑出後第二幅圖才出現。剛開始出現問題到網上搜發現有的說定時器動畫可能會造成這種情況,於是我在代碼調試裡註釋掉了定時器,讓圖片只走一步就停下來,發現後邊還是有空白,所以確定不是定時器的問題。於是我查看了一下盒模型,發現包裹img的容器寬度p#main並不是我理想中六張圖片寬度的總和,原來是我沒有明確設定這個容器p#main的寬度。但是問題來了,沒有明確地設定容器寬度,大家可能就會感性的認為容器的寬度不應該是被其內容填充而適應的麼?根據前面所述的現象,答案自然是否定的,也可以說不是所有情況都是如此,因為實際上定位對容器的寬度也是有影響的。以下討論絕對定位元素的大小與放置狀況的關聯。
二、包含區塊
首先我們回顧一下包含區塊(定位情境)的基本概念:
1.初始包含區塊(根元素的包含區塊)由用戶代理確定。
2.浮動元素包含區塊定義為最近的區塊級祖先元素。
3.相對定位或靜態定位元素包含區塊由最近的區塊級框、表格單元格、或行內區塊框祖先元素(任何類型)內容邊界構成。
4.絕對定位元素包含區塊設定為最近的定位不是static的祖先元素(任何類型)的邊框界定(對區塊級父元素)或內容邊界界定(對行內父元素)。
三、寬度與偏移
一般的,元素的大小和位置取決於其包含區塊。定位是元素各外邊距邊界相對於其包含區塊對應邊(內邊界與邊框相鄰邊)進行偏移,影響的是元素的所有一切(外邊距、邊框、內邊距、內容)都會移動。故對於一個定位元素有下列等式(後邊的計算皆基於此式):
left+margin-left+border-left-width+padding-left+width+padding-right+border-right -width+margin-right+right=包含區塊的width (式1-1)
據此,在未定義元素的寬度width和高度height時,其值大小都會受到定位影響。對於定位元素來說,是否需要設定其寬度高度應根據情況決定。考慮以下幾種情況其寬度高度各是多少的確定規則:
1.如果將偏移屬性top,left,bottom,right都進行了確定,而未設定外邊距,內邊距和邊框的時候,是否明確設定寬度高度,其值都是由偏移屬性決定的;反之若設定了外邊距或內邊距(auto也算),邊框時,高度寬度就是其明確設定值,未顯式設寬高的仍由偏移屬性決定。
2.對於非替換元素水平軸行為:
1)如果left,width,right都為auto,且沒有設定內外邊距,邊框,則經過計算元素左邊位於其靜態位置(從左到右讀),width“恰當收放”,根據上述等式right為餘下的水平距離;
2)當等式中所有值為固定值時,若元素“過度受限」則right會根據上式重置;
3)當上述等式中只有一個屬性值為auto時,元素「過度受限」時就會重置這一屬性值以滿足等式;
4)垂直軸規則類似,但要注意只有top可以取靜態位置,bottom做不到。
3.對於替換元素(注意這裡沒有「恰當收放」的概念,因為替換元素有固有寬高):
1)先看其width(height)是否顯式聲明,明確聲明則為該值,否則由元素內容實際大小(寬高)決定;
2)再看left,top若為auto則替換為靜態位置;
3)再看如果left和bottom值如果還為auto,則令margin的auto都置0,若未被置0就設定為左右相等,上下相等;
4)在此之後如果只剩下一個auto值,則同非替換元素類似,根據等式重設該auto值。
5)當元素「過度受限」時,與非替換元素處理一樣,使用者代理程式會忽略right(從左到右讀)和bottom。
以上就是對一個絕對定位元素實際顯示的寬度高度的影響因素情況分析,當你發現界面顯示的效果與你預想的不一致時,可以考慮從上述角度分析一下看是否需要重新確定元素的寬度高度值,或以上其它屬性的值。
四、一種常見的情形分析
現在來結合我在專案中遇到的寬度高度問題實際範例分析。這裡討論的假定情形為:設定好寬高的最外層p#rel為相對定位,其子p#abs僅設定left為固定值而未設定寬度(沒有內外邊距邊框前提),p#abs內部包含不同類型的元素。
1.先討論最內層包裹的是區塊級元素的情況,程式碼見下:
<p> </p><p> </p><p></p> <p></p>
*{margin:0;padding: 0}#rel1{position: relative;width: 120px;height: 50px;background-color: yellow;}#abs1{position: absolute;top: 0;left: -15px}#box1{width: 50px;height: 50px;background-color: red}#box2{width: 50px;height: 50px;background-color: blue}
# 由程式碼可知,我們將絕對定位元素的margin,padding都置0,且無邊框,則上述式1-1化為:
絕對定位元素p #abs的left+width+right = 包含塊p#rel的width
由於絕對定位元素的left是定值,而未設width和right,所以後兩者都是初始值auto,根據非替換軸的水平行為1)可知,先將width恰當收放,也就是以絕對定位元素的子元素內容剛好放好為準,再自動計算right的值,使三個屬性總和剛好等於絕對定位的包含塊p#rel的寬度120px。因此,此時絕對定位的元素p#abs的寬度width的值由其內容決定,在如下圖兩種情形下(透過程式碼改變子p#box1的寬度進行測試),絕對定位元素的width總是等於子p中寬度最大的那個值。且不受left值的影響,因為無論left值為多少,其right的值都會自動調整,從而不影響width的值。
情況,代碼及示意圖如下:
<p> </p><p> <img alt="詳解css絕對定位對元素寬度的影響" > <img alt="詳解css絕對定位對元素寬度的影響" > </p>
*{margin:0;padding: 0}#rel2{position: relative;width: 120px;height: 50px;background-color: yellow;}#abs2{position: absolute;top: 0;}img{float:left}#img1{width: 50px;height: 50px}#img2{width: 50px;height: 50px}其中,絕對定位元素的left將被設為定值,而width根據「恰當收放」的原則,它的最大值應該是行內子元素寬度之和,最小值應該是子元素中寬度最大者的寬度值,而right的值情況有一點複雜,因為默認情況下,塊級元素是垂直排列而行內元素都是一個挨著一個(中間的縫隙可以用:float:left清除)從左到右排列,且中間沒有換行符。所以行內元素放在絕對定位的塊級元素內作為元素內容寬度過寬時,會由於其行內元素的特徵將內容撐開一直到其包含塊內容區右邊界(從左向右讀),因此當行內子元素(即絕對元素的內容)受限出現折行時right的值為0,式1-1便化為如下:###### ###### +width = 包含區塊p#rel的width###### ###### 當然這種情況應該是在left設定值在一定範圍內的前提下(因為寬度沒有設置,是auto的) ,那麼如何確定這個範圍呢?當絕對定位元素的寬度剛好等於其最小值和最大值時,利用上面的公式求出left的範圍設定在(包含塊width-最大絕對定位元素width)~(包含塊width-最小絕對定位元素width)之間時,絕對定位元素的寬度是受left值影響的,可以透過上面的公式求出當left為某一特定值時的絕對定位元素的width。 ###### 當left的值設定在上面所說的範圍之外時,絕對定位元素的width已經達到了極值,就不會再受left變化而影響了,此時right就不再是0,而會自動進行計算以滿足下述公式:###### ####
絕對定位下上「中」的
# 3.總結來說,在前提假定的情況下:
1)如果絕對定位元素包裹區塊級元素,則其width值始終等於子元素中寬度最大者的值。 2)如果絕對定位元素包裹的行內元素,則其width值最大為子元素寬度之和,最小為子元素寬度最大者的值;並需先求出影響width值的left區間,在用其包含塊的寬度-left值來求其寬度。 五、總結 兜兜轉轉說了這麼多,其實就是一個道理,如果你擔心絕對定位元素的寬度出現問題的話,最好明確地給它設定一個width固定值,因為根據規則1,在沒有將四個偏移屬性全部設定的前提下,顯式的width值是管用噠~然而在實際環境中,設定寬度高度對定位元素來說不一定必要,所以理解寬度高度的影響因素將會對遇到的一些關於效果顯示的問題更有幫助。這是我第一次寫科技博文,首先我要向替我審校的本人優雅的攻城獅男友致以最真摯的謝意,同時感謝O'Reilly叢書《CSS權威指南第三版》的作者及其相關工作人員,本文大量內容皆是參考該書並加以自己的理解所寫,初次發文如有問題,還請大家批評指正,非常感謝各位~以上是詳解css絕對定位對元素寬度的影響的詳細內容。更多資訊請關注PHP中文網其他相關文章!