神奇的CSS盒子模型
CSS盒子模型:就是用來裝頁面上的元素的矩形區域。CSS中的盒子模型包括IE盒子模型和標準的W3C盒子模型。這兩種盒子模型都包含有內容(content)、填充(padding)、邊框(border)、邊界(margin)這四個組成部分,這四個部分都包含有top/right/bottom/left四個組成部分。
那這兩個盒子模型有什麼不同的地方呢?我們先來看看以下兩張圖:
從圖中我們可以看出,這兩種盒子模型最主要的區別就是width的包含範圍,在標準的盒子模型中,width指content部分的寬度,在IE盒子模型中,width表示content+padding+border這三個部分的寬度,故這使得在計算整個盒子的寬度時存在著差異:
標準盒子模型的盒子寬度:左右margin+左右border+左右padding+width
IE盒子模型的盒子寬度:左右margin+width
在CSS3中引入了box-sizing屬性,box-sizing:content-box;表示標準的盒子模型,
box-sizing:border-box表示IE盒子模型。預設的情況下是標準盒子模型,仔細觀察一下兩張圖就可以看出他們之間的區別了:
(1) 第一張是標準的盒子模型:
(2) 第二張是IE盒子模型:
說完了這兩種盒子模型,接下來就說一下盒子模型的margin屬性吧:
加上margin之後:就可以實現一側定寬佈局了
(2)margin可以改變元素佔據的尺寸:
(1) block/inline-block水平元素都適用
(2) 與是否設定width/height值沒有關係
(3) 適用於水平和垂直方向上
由上圖可以看出,當改變margin的值的時候,容器所佔據的尺寸也將發生變化。
(3)margin與百分比單位之間的關係(普通元素的百分比以及絕對定位的百分比之間的關係):
(1)普通元素的margin的百分比是相對於容器的寬度來計算的。
(2) 絕對定位的百分比margin的值是相對於第一個定位(relative/absolute/fixed)祖先元素的寬度來決定的。
(4)margin的重疊性:
(1) margin重疊只發生在block的水平元素上。(不包括float/absolute元素)
(2) margin重疊垂直方向上,margin-bottom/margin-top方向上。不考慮書寫格式。
發生margin重疊的三種情景:
(1) 相鄰的兄弟元素
(2) 父級元素和第一個或最後一個子元素
(3) 空的block元素
A、相鄰的兄弟元素之間發生重疊
B、父級元素與第一個或最後一個子元素
以上三種情況的結果都是
父級元素和子元素髮生margin重疊的條件:
(1) margin-top重疊:
a. 父級元素是非塊狀格式化上下文元素
b. 父級元素沒有border-top的屬性
c. 父級元素沒有padding-top的屬性
d. 父級元素和第一個子元素之間沒有inline的內聯元素
(2) margin-bottom重疊:
a. 父級元素是非塊狀格式化上下文元素
b. 父級元素沒有border-top的屬性
c. 父級元素沒有padding-top的屬性
d. 父級元素和第一個子元素之間沒有inline的內聯元素
e. 父元素沒有height,min-height,max-height的限制
如何防止父級元素和自己元素髮生margin重疊:
(1) 防止margin-top重疊:
a. 在父級元素中加上overflow:hidden;
b. 在父級元素中加上border-top:1px solid #000;
c. 在父級元素中加上padding-top:1px;
d. 在父元素和第一個子元素之間加上內聯元素。
(2) 防止margin-bottom重疊,與上面相似,另外可以設定父級元素的高度消除margin重疊。
C、空block元素的margin重疊
效果是son的div只有1em並非2em。
空block元素髮生margin重疊的一些條件:
a. 元素中沒有border設定
b. 元素中沒有padding設定
c. 元素中沒有inline的內聯元素
d. 沒有hieght/min-height的設定
如何防止空block的margin重疊:
a. 給son元素設定一個border
b. 給son元素設定一個padding
c. 給son元素設定一個inline的內聯元素
d. 給son元素設定一個height
margin的計算規則:
(1) 正正取大值
(2) 正負值相加
(3) 負負最負值
A.正正取大值
正負值相加:
負負取負值:
相鄰重疊絕對值取最大負值,負值重疊絕對值取最大的負值,自身重疊的高度為0
(5)margin:auto時的一些應用情況:
上面的例子中圖片為什麼不水平居中?這是因為此時的圖片是inline水平的,即使沒有設定width也不會佔據整個容器,解決方法是將img的display設定為display:block就可以實現水平居中。(因為圖片是一個替換元素)
為什麼容器已經定寬定高了,為什麼margin:0 auto就是不居中呢?
那該如何設定元素的居中呢?
a. 通過writing-mode實現垂直居中。更改流的方向為垂直方向。
b. 絕對定位元素的margin實現垂直居中,只有ie8+以上的瀏覽器才支援。
(6)margin取負值時的應用:
(1)margin實現兩端對齊
(2)margin負值下的等高佈局:改變元素的佔據空間
(3)margin負值下的兩欄自適應佈局:元素佔據空間隨著margin的移動而改變
(7)margin在某些情形下會實效,為什麼??
(1) inline水平元素的垂直方向上的margin是無效的
前提:元素是非替換元素,比如不是img元素; 正常的書寫模式
(2) 可能發生了margin重疊
(3) display:table-cell/display:table-row的margin值無效,但是替換元素的display:table-cell/display:table-row的margin值是有效的
(4)絕對定位元素img設定了top和left的值,此時即使設定了margin-right或是margin-bottom的值也是不會改變圖片的位置的。
想要實現新增margin-right或是margin-bottom起作用,就要在容器中新增position:relative的屬性。
(5) margin的值太小使得margin屬性不起作用:
(6) 內聯特性導致的margin無效
由於要跟內聯元素的下邊緣對齊,故當圖片的margin-top小到一定值的時候再減小margin-top的值是不會改變圖片的位置的。(8)瞭解margin-start/margin-end屬性。
(1)在正常的流中,margin-start與margin-left是等效的,兩者是重疊的不累加的。(從左到右的流中)
(2)如果水平流是從右往左的,margin-start與margin-right是等效的。
(3)在垂直流的方向上,(writing-mode:vertical-*)margin-start相當於margin-top。
(9)瞭解margin-collapse屬性
-webkit-margin-collapse:<collapsed>|<discard>|<separate>
<collapsed>預設/重疊
<discard>取消
<spearate>分隔