前端--关于CSS盒模型
CSS樣式規則的學習是很繁瑣和枯燥的,因為它不像物理、數學或者其他編程語言一樣有一些基本概念、有一些基本公理或者規則,其他所有的表現都是概念在這些公里或者規則之下的邏輯游戲,CSS是有一些基本概念,但它沒有說給你幾條規則然后所有的表現都是在這些規則之下的任意自由組合,你要推測一個樣式聲明塊的在頁面中具體是怎樣表現的,你幾乎靠非常少是靠邏輯推理去推測出來,絕大多數是你知道并記住了這種寫法的聲名塊是具有怎樣的表現的。之所以為這樣也是因為樣式的組合太繁瑣組合情況特別多,像同樣的概念margin在塊級中的表現和在行內元素中的表現是不一樣的,即便是同樣在塊級元素中不同方向上的margin表現也是不一樣的,再進一步就算是同樣在塊級元素中同樣的方向上,父元素的某些屬性不同其表現也是不一樣的,再加上浮動定位又是另一種情況,要是再考慮到各種不同瀏覽器的兼容性的話那就更令人煩躁了,這樣的特性是不可能存在一個或幾個規則讓你邏輯推理樣式表現的,掌握CSS樣式規則只有窮舉各種各樣的組合并且記住它們的表現(雖然可能會有一小點的邏輯推理),因此前端這個職業感覺工作經驗比其他的編程語言更加重要一些。
掌握一門語言的結果是在頭腦中可以形成一個清晰的知識系統脈絡圖,而CSS的學習很難有一個清晰的邏輯線路去循環漸進的學習,因為它的概念關聯性太弱了,所以在沒有很清晰的邏輯幫助理解概念時,很好的理解現有概念是非常有必要的,比如說盒模型。
盒模型以及相關知識點在CSS中占有非常重要而核心的地位,而大家常常聽到的非常經典的對盒模型的理解就是一個盒子的類比,盒子本身是border,里面貨物就是內容,填充就是padding,盒子在擺放的時候要分開一定的距離就是margin。這種類比有它的好處,但是仍然感覺像是和沒說一樣(至少我這么覺得)。而且這種類比無形中把padding和內容這個整體視為標簽元素的內容,把margin視為內容以外的東西,感覺這對理解css布局的相關本質會造成一定的偏差,最明顯的一個例子就是初學人員會完全沒有意識到width和height指定的寬和高是內容的寬和高(css3加了新的屬性可以更改寬高的指定范圍),并不是把padding和border還有margin算在一起的。所以現在我并不想把內容、padding、border、margin放到一個盒子相關中去理解,以一個不是盒模型的角度去理解也同樣可能(只是可能因人而異)有利于避開在盒模型類比下形成想當然的認識。
在起初接觸前端的時候都會看到這樣的話:html標記頁面內容,css表現頁面樣式,javascript控制頁面行為。這是說頁面的內容都是用html標簽標記出來的,一個內容一定有一個相關html標簽去標記它;css做到的是表現與內容分離,也就是說css是為頁面的內容添加各種各樣的樣式,它的操作目標是內容,所以關于CSS的概念以內容為起點討論,而不以盒子為起點。
打開網頁可以發現頁面的內容范圍是文字、表單相關(輸入框、按鈕、單選框、復選框、下拉框)、圖片、音頻、視頻。內容在頁面中會放到一個矩形區域中即內容區,控制該區域的寬高屬性為width和height,在內容區外部分則是標簽元素形成的用于布局用的額外的空間。
標記這些內容的html標簽分為兩種:替換元素與非替換元素。
替換元素:以上除了文字都是替換元素,替換元素是指這個標簽元素為某個內容的占一個位子,在原始html代碼中看不出來實際具體表現。像圖像、音頻、視頻標簽它們就是指向某個圖片文件、音頻文件、視頻文件。起占位作用的標簽就是一種替換元素。
非替換元素:標簽元素標記的內容在原始html代碼中可以看出來,就不如說用span標簽標記的文本。標記文本的span標簽就是一種非替換元素。
因為內容總是有一個標簽來標記它,而標簽在瀏覽器中的渲染結果就是在內容周圍變成一個矩形區域(在CSS3中可以設置為非矩形區域),這種矩形區域會在內容周圍生成額外的空間,而產生的額外空間的種類一共有三種:padding(內邊距)、border(邊框)、margin(外邊距)。在正常文檔流中css對內容的樣式布局實現大部分就是通過設置padding、border、margin來實現的。
padding空間是在邊框和內容區域之間的無色透明的一塊區域,該區域可以看到元素的背景色并且在沒有border和margin的情況下該區域是不能合并的。
border空間是在內邊距和外邊距之間的一塊有內置樣式有顏色的一塊區域,該區域也是繪制在背景色之上的,因此如果邊框有鏤空是可以看到背景顏色的。
margin空間是在邊框外面的一塊無色透明區域,該區域可以看到父元素的背景色并且在正常流中垂直方向上該區域是可以合并的,水平方向上是不存在合并規則的。
以上三個空間區域在在默認情況下都是不存在的。
雖然每個元素都會在內容周圍渲染成矩形區域,但不同元素默認渲染成的矩形區域類型可能是不同的。通過設置display可以在不同類型的矩形區域之間進行切換。對矩形區域分類的一個標準就是看矩形區域前后是否有換行符:前后都有換行符的矩形區域為塊級矩形區域;前后沒有換行符的矩形區域為行內矩形區域。相應的不同類別的矩形區域所對應的元素也就叫做塊級元素或者行內元素。換行符只是塊級和行內與否的一條區分標識,并不是區別的全部,他倆在默認狀態和變化行為上也有些許差別。
在文檔流中默認狀態下,多個塊級元素是垂直排列的,并且它的寬為父元素的內容區域寬,高為自己內容區域高,可以自由改變自己內容區的寬和高。而多個行內元素是橫向排列的,它的寬和高都為內容區域的寬和高,并且不能設置內容區的寬和高。
這樣,一塊標簽標記的內容在頁面中的表現從里到外就是內容區、內邊距、邊框、外邊距四部分,這四部分是緊密相連的,并作為一個整體放在一個布局上下文中,并基于這個布局上下文擺放。布局上下文是父元素的內容區,這個內容區可能在塊級元素中也可能在行內元素中。一般情況下,各個標簽內容能按照從左到右的順序擺放的就按照從左到右的順序擺放,從左到右擺放不下的(像超出或者有換行符)就按照從上到下的順序擺放,如果一個元素標簽處在這樣一個擺放順序中,就說這個標簽在文檔流中。只有浮動和定位會擺脫這種束縛,這時就說元素脫離了文檔流。
?
矩形區域中各個屬性的取值只有margin可以取負值,只有width和margin可以取auto關鍵字,border不能為百分數,其他屬性都只能取 正的數字或者正的百分數。其中margin和padding設置的值是一個塊區域的垂直高度,這塊區域的長和寬是隨著內容的width和height變化 而變化的。border設置的是自身的寬度,其長度也是隨著相應邊的長度變化而變化的。padding和border的取值是不會根據某些條件自動改變 的,一旦設置就不會發生改變。margin的取值雖然可以自動變化,但產生變化的條件一般都是空間受限。取值可以根據內容變化而變化的只有width和 height屬性,前提是width、height取值為auto。下面根據塊級和行內分開討論,并在各種情況下再根據水平方向和垂直方向分開討論。
1.塊級矩形區域中:
在 水平方向上,如果width沒有設置固定值即值為auto的時候,width屬性有盡可能寬的傾向,比如若width和margin同時設置為auto, 那么margin的值會被瀏覽器重置為0。如果為width設定了固定值,那么它的值就是固定的了,不論是否脫離文檔流是否超出了父元素的內容區。
1. 當width設置為auto的時候,這種情況下width有一條原則:若該內容區在布局上下文中(父元素的內容區)則它的width會盡可能的大。若該內 容區因為正的margin的原因全部超過了布局上下文,或者padding、border大于了布局上下文的寬,那么它的width取值是為0的,雖然 width為0,但內容還是存在的并且padding和border屬性值也都是不會改變的。但還存在一種情況,就是當padding和margin同時 存在的時候,正數的margin-right不能使元素的矩形區域離開父元素的內容區,其數值再大也無效。而正數的margin-left可以是元素的矩 形區域離開父元素的內容區。另外一條特殊性原則就是當margin為負的情況了,負數產生的效果就是把內容區穿過布局上下文并往布局上下文外側移動相應的 距離。當一側margin為負數的時候,并還存在三種可能情況:另一側margin沒有數值、另一側margin有正值、另一側marging有負值。 另一側margin沒有值的時候,width會一直延伸。另一側margin有正值的時候,根據正數的大小,以負數margin位置和正數margin位 置為內容區的兩邊,自動調整width的大小,當正數margin延伸的位置與負數margin所在的位置重合的時候,width變為0。另一側 margin有負值的時候,內容區兩邊向布局上下文外側左右延伸。
2.當width設置為固定值的時候,這種情況看起來復雜度低一些,畢竟可以自 己改變的量只剩下了margin。此時如果在內容區兩邊同時添加左右padding是不會有任何沖突的,但是若同時添加左右margin就很可能產生沖突 了。因為width是固定的,若固定一邊的margin,那么另一邊的margin也會是固定的,但另一邊的固定的值很可能不是你設置的那個值。這時候這 個矩形區域就會受限,首先的處理方法就是有一個優先級,如果左右margin相互沖突,那么優先滿足左邊的margin,如果上下margin相互沖突, 那么優先滿足上面的margin。像固定寬度的情況下兩邊都是負數的margin,那么元素會優先向左邊移動。還有一個特殊用法是關于水平居中,即當左右 兩邊margin設置為auto,并且width為固定值,則該內容區域在布局上下文中水平居中。
左右負外邊距還有一個特殊的規則,就是如果左外 邊距為負數,并且元素都超出了瀏覽器,那么它就真的超出看不見了,不會在瀏覽器下面形成滾動條。如果右外邊距為負數,并且元素向外移動超出了瀏覽器,那么 它是不會消失看不見的,因為會在瀏覽器下面形成滾動條。還有在正常情況下,漢字在父元素高度允許的情況下會自動換行,若父元素的高不足以容納所有漢字,并 且父元素也沒有設置over-flow屬性,那么漢字內容就會超出父元素。而單詞要想換行的話除了父元素高度要允許,還是額外設置word-wrap和 word-break屬性。
在垂直方向上,垂直方向上的情況比水平方向上的還要復雜一些,因為margin在垂直方向上可以合并而在水平 方向上是不會合并的。垂直方向上的height屬性不會像width一樣默認情況下會盡量延展,而是會盡量雖小剛好為內容高度。這樣在height為 auto,并且父元素沒有adding和border空間的時候,最高塊級子元素和最低塊級子元素的margin范圍是不會在父元素的內容區內的,它倆 margin作用范圍和父元素的margin是一樣的(都是父元素外的margin空間),并且有合并效果。如果父元素有border或者 padding,那么這倆空間就會阻擋最高和最低塊級子元素的margin作用范圍超出其布局上下文,并會增加父元素的height數值。還要注意若 padding或margin設置為了百分數,那么不管垂直還是水平方向這百分數的參照都是父元素的width。在一個布局上下文中,其中的各個塊級子元 素之間的相對位置是一定的,如果一個子元素位置發生了變化,那么它下面的子元素為了維持和原來一樣的相對位置也會隨著產生相應的位置變化。這在負的外邊距 情況下要特別注意,負的外邊距根據父元素的height是否為auto表現的也不是很一樣。這種不一樣主要表現在最后一個塊級子元素上,前面說過當 margin-top的值和margin-bottom的實現沖突的時候要優先實現margin-top的值,因為塊級子元素在布局上下文中根據 margin可以自由調整位置的,所以第一個和中間的子元素是不存在margin-top和margin-bottom沖突的情況的,唯一可以出現沖突的 情況就是最后一個塊級子元素,因為最后一個塊級子元素的margin-bottom是對父元素內容區的下邊界產生作用的,如果這個下邊界可變就沒有沖突, 如果這個下邊界不可變就可能會有沖突,這個下邊界可變與不可變就是父元素的height是否為auto決定的。當height為auto的時候,塊級子元 素所有的負的margin都會產生父元素變短的效果,若height為固定值,那么最后一個塊級子元素的margin-bottom不會有任何作用。
2.行內矩形區域中:
行 內矩形區域(盒模型)就簡單一些了。首先行內矩形區域的width和height的設置是無效的,它只會根據內容的大小自動調整自己的大小。在外邊距方 面,margin的垂直設置是不會有任何效果的,因為它畢竟在行框內,margin改變不了行間距。而水平的margin是可以有相應的效果的。同樣的 padding,border的垂直設置也同樣是不會改變行間距的,因此看不出效果,除非有背景或者顏色會有一些效果,比如說會遮蓋住相鄰上下兩行的內 容,但行間距還是沒有改變的。水平設置倒是也同樣會有相應的效果。
轉載于:https://www.cnblogs.com/jinjilin/p/5047255.html
總結
以上是生活随笔為你收集整理的前端--关于CSS盒模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 因xhost命令和DISPLAY环境变量
- 下一篇: 2017年html5行业报告,云适配发布