css是一門具象語言,並不像js那樣具備邏輯性,所以,就算入行了前端好久的工程師,也以爲css難以掌握。下面咱們就一步一步揭開css的神祕面紗,深刻理解css盒模型,這對咱們在佈局上會有一個質的提高。css
相信不少人對這幅圖都不陌生,盒子模型簡單點理解就是外邊距(margin)+邊框(border)+內邊距(padding)+內容(content),頁面所呈現的效果其實就是一個個盒子堆疊而成的。每個元素實際上是包含了一個「外在盒子」和一個「內在盒子」,其中「外在盒子」負責元素是一行顯示仍是換行顯示,而「內在盒子」則負責寬高、內容展示。咱們都知道inline-block(inline對應於「外在盒子」,block對應於「內在盒子」),而block能夠簡單地理解爲block-block,table爲block-table(由於還有一個inline-table)。html
內容區域(content area)。內容區域指的是一種圍繞文字看不見的盒子,其大小僅受字符自己特性控制,本質上是一個字符盒子(character box);可是圖片這樣的替換元素,其顯示內容不是文字,所以內容區域能夠當作是元素自身。 前端
內聯盒子(inline box)。「內聯盒子」不會讓內容成塊顯示,而是排成一行,這裏的內聯盒子指的是元素的「外在盒子」,用來決定元素是內聯仍是塊級。該盒子又能夠細分爲「內聯盒子」和「匿名內聯盒子」。以下:
css3
行框盒子(line box)。每一行就是一個行框盒子,每一個行框盒子都是由一個個內聯盒子組成,注意:line-height是做用在行框盒子上的,並最終決定高度(替換元素除外,後面會講解什麼是替換元素)。canvas
包含盒子(containing box)。此盒子由一行一行的「行框盒子」組成(css規範中,並無「包含盒子」的說法,更準確的稱呼是「包含塊」(containing block)。瀏覽器
width的默認值是auto,但不少人卻都不理解這個值是什麼意思,由於auto在不一樣場景會有不一樣的表現:ide
fill-available:充分利用可用空間,例如div、p這些元素的寬度是默認100%於父級容器的。可是width: auto卻不一樣於width: 100%,這是不少人不理解的地方。若是你設置了width: 100%,這裏指的是內容區域100%,即css3中的content-box,這時若是你設置了padding、border或者margin,元素都會撐破父元素,從而破壞佈局。你固然能夠設置box-sizing: border-box,但惋惜的是css3中沒有margin-box,這時候你若是設置了margin,依然會撐破父元素,可是width: auto卻不會,以下所示:佈局
fit-content:收縮到合適,典型表明浮動、絕對定位(有例外,設置了對立屬性:left、right、top、bottom時,寬度和高度由祖先元素position非static的元素決定,可是替換元素除外:img、video、canvas等)、inline-block、table。利用這個特性咱們能夠實現,文字總體居中,多行則居左顯示,以下:字體
min-content:收縮到最小。在表格中最多見,當每一列空間都不夠的時候,文字能斷則斷,中文隨便斷,英文單詞不能斷。能夠根據這個特性實現凹凸圖形等效果,以下:spa
max-content:超出容器限制,內容很長的連續英文或數字,或者內聯元素被設置爲了white-space: nowrap。
height的默認值也是auto,指的是其高度由內部元素堆疊而成,內部元素盒子有多高,元素就有多高。但在絕對定位中,若同時設置了top與bottom,則其高度由父盒子高度減去top與bottom。
height: 100%。若是父元素height爲auto,則子元素height:100%是無效的,要想子元素height: 100%生效,則:
因爲替換元素在不少表現上都與普通內聯元素不同,所以在這裏着重介紹一下替換元素。
padding與內聯元素。padding做用在塊級元素上會影響盒子的寬高,可是若是做用在內聯元素上(不包括替換元素),彷佛就只能做用在水平方向上,垂直方向上就沒看到任何影響。但事實並非沒有影響,只是視覺上咱們以爲沒有影響而已。由於內聯元素沒有可視寬度和可視高度的說法(clientWidth和clientHeight永遠是0),垂直方向徹底受line-height和vertical-align的影響,視覺上並無改變上一行和下一行內容的間距,所以,給咱們的感受就是垂直方向上padding沒有起做用。利用這個特性,咱們能夠在垂直方向上增大可點擊區域,這樣既不會破壞現有佈局,也能很好地響應用戶的點擊。特別是在移動端,一個關閉的「x」若是過小,用戶就很難點擊到,調大字體又會影響佈局,這時候就能夠用到padding。
padding的百分比值。padding不支持負值,padding百分比不管寬高都是相對於width來講的,另外padding區域是跟着行框盒子走的。所以,若是padding做用於內聯元素,則寬度和高度細節有差別,而且padding會斷行,其緣由在於strut,意思是說每個行框盒子前面都有一個不可見的盒子,其line-height和font-size都繼承於父元素,稱爲strut。利用padding的這些特性,咱們能夠實現以下效果:
margin: auto生效的前提是元素在width和height爲auto的時候可以自動填充容器,這樣,在設置width或height的值時,若是還有剩餘尺寸,margin: auto就能夠利用剩餘尺寸。所以在絕對定位元素設置了top、bottom、left、right的狀況下,就能夠很方便地實現水平垂直居中,以下:
margin改變元素尺寸。在元素width爲auto的狀況下,margin正值和負值都能改變元素的尺寸。以下:
margin負值。margin支持負值,而且用途十分普遍,例如,在等寬的盒子中,最後一個元素不因margin-right而折行;實現等高佈局等。以下:
盒子並列佔滿父元素:
等高佈局,其原理是利用padding撐開一片足夠大的高度,再用margin負值將頂下去的元素收回來:
margin合併。塊級元素的上外邊距與下外邊距有時會合併爲單個外邊距,這種現象稱爲「margin合併」。通常會有如下三種:
一、相鄰兄弟元素margin合併
二、父級和第一個/最後一個子元素合併
margin-top合併,解決方案: 父元素設置爲塊狀格式化上下文元素 父元素設置border-top值 父元素設置padding-top值 父元素和第一個子元素之間添加內聯元素進行分隔 margin-bottom合併,解決方案: 父元素設置爲塊狀格式化上下文元素 父元素設置border-bottom值 父元素設置padding-bottom值 父元素和最後一個子元素之間添加內聯元素進行分隔 父元素設置 height、min-height 或 max-height。
三、空塊級元素的margin合併,即自身有margin-top和margin-bottom,但元素是空的,此時會合併爲一個margin。
margin無效。margin在某些場景下會失效,但有些「失效」只是視覺上的表現而已。以下:
相信很多同窗都使用過border來製做圖形,例如三角形、圓形等等,此處就不舉例子,主要講講等高佈局,代碼和效果以下所示:
其原理就是父元素撐開一個border-left,菜單欄左浮動,而且寬度跟父元素border保持一致,經過margin-left負值往左偏移到border位置,另外父元素設置僞元素after來清除浮動,這樣就能夠實現左側固定,右側自適應的兩欄等高佈局。
參考資料:《CSS世界》