摘要:下面我們就一步一步揭開的神秘面紗,深入理解盒模型,這對我們在布局上會有一個質的提升。與內聯元素的百分比值與內聯元素。
css是一門具象語言,并不像js那樣具有邏輯性,因此,就算入行了前端很久的工程師,也覺得css難以掌握。下面我們就一步一步揭開css的神秘面紗,深入理解css盒模型,這對我們在布局上會有一個質的提升。
盒子模型
相信很多人對這幅圖都不陌生,盒子模型簡單點理解就是外邊距(margin)+邊框(border)+內邊距(padding)+內容(content),頁面所呈現的效果其實就是一個個盒子堆疊而成的。每一個元素其實是包含了一個“外在盒子”和一個“內在盒子”,其中“外在盒子”負責元素是一行顯示還是換行顯示,而“內在盒子”則負責寬高、內容展現。我們都知道inline-block(inline對應于“外在盒子”,block對應于“內在盒子”),而block可以簡單地理解為block-block,table為block-table(因為還有一個inline-table)。
內容區域(content area)
內聯盒子(inline box)
行框盒子(line box)
包含盒子(containing box)
內容區域(content area)。內容區域指的是一種圍繞文字看不見的盒子,其大小僅受字符本身特性控制,本質上是一個字符盒子(character box);但是圖片這樣的替換元素,其顯示內容不是文字,因此內容區域可以看成是元素自身。
內聯盒子(inline box)。“內聯盒子”不會讓內容成塊顯示,而是排成一行,這里的內聯盒子指的是元素的“外在盒子”,用來決定元素是內聯還是塊級。該盒子又可以細分為“內聯盒子”和“匿名內聯盒子”。如下:
行框盒子(line box)。每一行就是一個行框盒子,每個行框盒子都是由一個個內聯盒子組成,注意:line-height是作用在行框盒子上的,并最終決定高度(替換元素除外,后面會講解什么是替換元素)。
包含盒子(containing box)。此盒子由一行一行的“行框盒子”組成(css規范中,并沒有“包含盒子”的說法,更準確的稱呼是“包含塊”(containing block)。
widthwidth的默認值是auto,但很多人卻都不理解這個值是什么意思,因為auto在不同場景會有不同的表現:
fill-available
fit-content
min-content
max-content
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:收縮到最小。在表格中最常見,當每一列空間都不夠的時候,文字能斷則斷,中文隨便斷,英文單詞不能斷。可以根據這個特性實現凹凸圖形等效果,如下:
max-content:超出容器限制,內容很長的連續英文或數字,或者內聯元素被設置為了white-space: nowrap。
heightheight的默認值也是auto,指的是其高度由內部元素堆疊而成,內部元素盒子有多高,元素就有多高。但在絕對定位中,若同時設置了top與bottom,則其高度由父盒子高度減去top與bottom。
height: 100%。如果父元素height為auto,則子元素height:100%是無效的,要想子元素height: 100%生效,則:
父元素設定顯式高度值
使用絕對定位(絕對定位元素的百分比是根據padding box計算的,非絕對定位元素百分比是根據content box計算的)
替換元素由于替換元素在很多表現上都與普通內聯元素不一樣,因此在這里著重介紹一下替換元素。
根據“外在盒子”是內聯還是塊級,我們把元素分為內聯元素和塊級元素,而根據內容是否可替換,我們把元素分為可替換元素和非替換元素。
,
替換元素外觀不受頁面css的影響,有自己的尺寸,一般為300 * 150,在很多css屬性上有自己的一套表現規則,例如vertical-align默認就是元素下邊緣對齊,而不是基線對齊。
替換元素尺寸計算規則:css尺寸 > html尺寸 > 固有尺寸
內聯替換元素和塊級替換元素規則一致,即display: block,其寬度也不會100%。
替換元素固有尺寸無法更改,width和height改變的是content-box的寬高,而默認替換元素的object-fit是fill,也就是會填充content-box,因此看上去像是改變了固有尺寸。
替換元素before和after偽元素無效。
paddingpadding與內聯元素
padding的百分比值
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的這些特性,我們可以實現如下效果:
利用padding實現一個正方形
內聯元素padding高度差異(只需把font-size設為0即可變為正方形)
padding斷行(由于padding作用在行框盒子上,因此文字換行,padding也跟著換行,后面的背景蓋住了前面的,就形成了這種效果)
marginmargin: auto
margin改變元素尺寸
margin負值
margin合并
margin無效的情況
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合并”。一般會有以下三種:
1、相鄰兄弟元素margin合并
2、父級和第一個/最后一個子元素合并
margin-top合并,解決方案: 父元素設置為塊狀格式化上下文元素 父元素設置border-top值 父元素設置padding-top值 父元素和第一個子元素之間添加內聯元素進行分隔 margin-bottom合并,解決方案: 父元素設置為塊狀格式化上下文元素 父元素設置border-bottom值 父元素設置padding-bottom值 父元素和最后一個子元素之間添加內聯元素進行分隔 父元素設置 height、min-height 或 max-height。
3、空塊級元素的margin合并,即自身有margin-top和margin-bottom,但元素是空的,此時會合并為一個margin。
margin無效。margin在某些場景下會失效,但有些“失效”只是視覺上的表現而已。如下:
display 計算值 inline 的非替換元素的垂直 margin 是無效的,雖然規范提到有 渲染,但瀏覽器表現卻未尋得一點蹤跡,這和 padding 是有明顯區別的。對于內聯替換元素, 垂直 margin 有效,并且沒有 margin 合并的問題,所以圖片永遠不會發生 margin 合并。
表格中的
margin合并的時候,更改margin值可能無效。因為垂直方向上會發生margin合并。
絕對定位元素非定位方位的margin值“無效”(其實margin是有效的,只是元素絕對定位了,并不影響其相鄰元素的渲染)。
定高容器的子元素的margin-bottom或者寬度定死的子元素的margin-right的定位“失效”。這里的失效也是假的,原因跟絕對定位的margin無效類似,在一個默認流下,其定位方向是左側和上方,此時只有margin-left和margin-top可以影響其定位,而margin-right和margin-bottom則只會影響其相鄰元素,若此時沒有相鄰元素,則看上去像是margin無效。
內聯特性導致的margin值無效。一個div元素中有一個img圖片,我們對img使用margin-top負值,當margin-top負值達到一定值的時候,再往上圖片也不會上移。
border制作圖形
等高布局
相信不少同學都使用過border來制作圖形,例如三角形、圓形等等,此處就不舉例子,主要講講等高布局,代碼和效果如下所示:
其原理就是父元素撐開一個border-left,菜單欄左浮動,并且寬度跟父元素border保持一致,通過margin-left負值往左偏移到border位置,另外父元素設置偽元素after來清除浮動,這樣就可以實現左側固定,右側自適應的兩欄等高布局。
參考資料:
《CSS世界》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/113190.html
摘要:內聯盒子的高度由決定,限制包含盒子的高度,兩者一致,即把內聯盒子安放在包含盒子內,排除其他外界干擾。這時候由內聯盒子模型可知,行間距是等分的,中間部分是,達到看似居中的效果。可以得到結論和設置一致,并非是完全垂直,除非為。 張鑫旭的CSS深入理解之line-height學習筆記 line-height的定義 行高:兩行文字基線之間的距離 為何是基線:基線是定義所有字線的根本 不同字體...
摘要:常見問題這一部分我們來說一說常見的內聯元素的一些問題。通過設置為,或者使用屬性,都可以達到去除內聯元素之間的間隙的目的。 showImg(https://segmentfault.com/img/remote/1460000014515131?w=1280&h=608); 上一篇文章我們討論了font-size,這一篇來說另一個與文字關系密切的屬性line-height。這里涉及到了內...
摘要:常見問題這一部分我們來說一說常見的內聯元素的一些問題。通過設置為,或者使用屬性,都可以達到去除內聯元素之間的間隙的目的。 showImg(https://segmentfault.com/img/remote/1460000014515131?w=1280&h=608); 上一篇文章我們討論了font-size,這一篇來說另一個與文字關系密切的屬性line-height。這里涉及到了內...
摘要:去年就看到張鑫旭大神的這篇文章,看了好幾遍才看懂。而對于使用脫離文檔流的元素,其他盒子與其他盒子內的文本都會無視它。而這造成的顯示上的差異就是文檔流中的文字實體不會與浮動元素重疊,而會與絕對定位元素重疊。 去年就看到張鑫旭大神的這篇文章,看了好幾遍才看懂。后來再去想其中的一些原理,又忘了。于是打算把它記下來,一來做個備份,二來希望與君共勉。 這里我對文章以自己的理解做了一些精簡,完整版...
閱讀 807·2021-11-22 15:25
閱讀 1408·2021-09-08 09:45
閱讀 1684·2021-09-02 09:46
閱讀 1299·2019-08-30 15:56
閱讀 1528·2019-08-29 15:14
閱讀 1159·2019-08-29 13:06
閱讀 2010·2019-08-29 12:34
閱讀 1400·2019-08-26 12:14