前端--嘗試以新角度深入理解CSS盒模型(1),深入理解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可以在不同類型的矩形地區之間進行切換。對矩形地區分類的一個標準就是看矩形地區前後是否有分行符號:前後都有分行符號的矩形地區為塊級矩形地區;前後沒有分行符號的矩形地區為行內矩形地區。相應的不同類別的矩形地區所對應的元素也就叫做區塊層級元素或者行內元素。分行符號只是塊級和行內與否的一條區分標識,並不是區別的全部,他倆在預設狀態和變化行為上也有些許差別。
在文檔流中預設狀態下,多個區塊層級元素是垂直排列的,並且它的寬為父元素的內容地區寬,高為自己內容地區高,可以自由改變自己內容區的寬和高。而多個行內元素是橫向排列的,它的寬和高都為內容地區的寬和高,並且不能設定內容區的寬和高。
這樣,一塊標籤標記的內容在頁面中的表現從裡到外就是內容區、內邊距、邊框、外邊距四部分,這四部分是緊密相連的,並作為一個整體放在一個布局上下文中,並基於這個布局上下文擺放。布局上下文是父元素的內容區,這個內容區可能在區塊層級元素中也可能在行內元素中。一般情況下,各個標籤內容能按照從左至右的順序擺放的就按照從左至右的順序擺放,從左至右擺放不下的(像超出或者有分行符號)就按照從上到下的順序擺放,如果一個元素標籤處在這樣一個擺放順序中,就說這個標籤在文檔流中。只有浮動和定位會擺脫這種束縛,這時就說元素脫離了文檔流。