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