1. 程式人生 > >神奇的CSS盒子模型

神奇的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屬性吧:

(1)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>分隔