深入css布局 (1) — 盒模型 元素分类
?
深入css布局(1)—— 盒模型 & 元素分類
?
? ? “ 在css知識體系中,除了css選擇器,樣式屬性等基礎(chǔ)知識外,css布局相關(guān)的知識才是css比較核心和重要的點(diǎn)。今天我們來深入學(xué)習(xí)一下css布局相關(guān)的知識。”
?
首先來列下大綱
- 盒模型
- IE盒模型
- W3C盒模型
- box-sizing
- 元素的分類
- 塊級元素
- 行內(nèi)元素
- 行內(nèi)塊級元素
- 行框
- 定位與浮動
- 文檔流
- 包含塊
- 浮動清除
- margin問題
- 格式化上下文(formatting context)
- BFC、IFC、FFC、GFC
- 常見布局實(shí)戰(zhàn)
- 水平垂直居中
- 兩欄 & 三欄布局
- …
一、css盒模型
1.1 IE盒模型與W3C盒模型
首先大家都知道一個頁面是由眾多HTML元素組成的,每一個元素都有自己的一個矩形的顯示區(qū)域,這就是我們平時經(jīng)常提及的css盒模型。
這個盒模型或者說這個矩形的顯示區(qū)域呢 就是向下面這張圖一樣,包括四部分:
margin(外邊距) border(邊框) padding(內(nèi)邊距) content(內(nèi)容)?
?
在css的發(fā)展歷程中,有兩種版本的盒模型,一個叫
IE盒模型(又叫怪異盒模型),一個叫W3C標(biāo)準(zhǔn)盒模型,在早期的微軟出的IE瀏覽器中采用的是自己的盒模型標(biāo)準(zhǔn)成為IE盒模型或者叫怪異盒模型。 規(guī)定:元素width和height屬性是包含元素的border(邊框) padding(內(nèi)邊距) content(內(nèi)容)的。而后來W3C組織(中文叫做萬維網(wǎng)聯(lián)盟,是一家中立性的技術(shù)標(biāo)準(zhǔn)指定機(jī)構(gòu)),一個專門制定互聯(lián)網(wǎng)技術(shù)標(biāo)準(zhǔn)的機(jī)構(gòu),為了標(biāo)準(zhǔn)化前端的技術(shù)規(guī)范,他規(guī)定了個標(biāo)準(zhǔn)稱為W3C標(biāo)準(zhǔn)盒模型。
規(guī)定:元素width和height屬性只包含元素的content(內(nèi)容)。后來微軟也慢慢轉(zhuǎn)向了W3C的標(biāo)準(zhǔn),在IE6以后支持了W3C標(biāo)準(zhǔn)盒模型。在我們現(xiàn)在的主流瀏覽器里面默認(rèn)都是使用w3c標(biāo)準(zhǔn)盒模型。
我們來看下面這張圖
?
在圖的上半部分中展示的W3C盒模型標(biāo)準(zhǔn),比如我聲明一個div的width屬性為100px,那我只是規(guī)定了這個div的content內(nèi)容顯示區(qū)域的大小為100px,如果之后我再聲明div的padding為10px, border為15px solid black, 那么這個div最終的整體寬度就會變成
100 10 * 2 15 * 2 = 150px 了。而如果同樣的css運(yùn)用到了IE盒模型身上那么當(dāng)我規(guī)定div的width屬性為100px時,他整體的寬度就已經(jīng)確定了,就是100px,再之后我去聲明div的padding為10px,border為15px solid black,也不會影響我這個div的整體寬度,只是會壓縮這個div的content內(nèi)容顯示區(qū)域的大小。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style> #div1{ width: 100px; height: 100px; padding: 10px; border: 15px solid black; } /* 在W3C盒模型下 #div的整體寬度是150px; 在IE盒模型下 #div的整體寬度是100px; */ </style> </head> <body><div id="div1"></div> </body> </html>?
1.2 box-sizing
box-sizing干嘛用的?我們剛在說道目前主流瀏覽器默認(rèn)都是采用W3C盒模型,如果你就是想在這些瀏覽器里使用IE盒模型呢?你就需要使用box-sizing這個屬性,這是個css3中新出的屬性:默認(rèn)值是content-box就是指的使用W3C盒模型標(biāo)準(zhǔn),另外一個值是border-box,指的就是我要在這個元素上使用IE盒模型標(biāo)準(zhǔn)。
#div1 { box-sizing: border-box || content-box(默認(rèn)值) }那么這里就有個問題了,為啥W3C組織好不容易將IE盒模型摒棄調(diào),統(tǒng)一了前端這個盒模型標(biāo)準(zhǔn)而且所有瀏覽器廠商也都默認(rèn)支持了,現(xiàn)在反而在css3中加入了box-sizing屬性讓我們可以自由選擇盒模型標(biāo)準(zhǔn)了呢?
答案就是W3C突然發(fā)現(xiàn)在某些情況下,IE盒模型比自己家的那個盒模型標(biāo)準(zhǔn)更好用。 =。=…(這就很尷尬了…) 于是在css3中加入了box-sizing這個屬性讓開發(fā)者可以自由選擇要使用哪種標(biāo)準(zhǔn)(估計(jì)是被噴慘了…)
我們來看這樣一個例子:如果現(xiàn)在我們要實(shí)現(xiàn)這樣一個簡單布局,我要一個div的整體寬度是頁面的50%,并且呢這個div還帶有一個10px的邊框。我們要怎么做呢?
如果我們用IE盒模型標(biāo)準(zhǔn)的話就很簡單
就可以了 是吧。
那么如果我們使用W3C盒模型呢。
我們知道如果我們聲明這個div寬度為50%,然后聲明border為10px的話 那么這個div實(shí)際寬度應(yīng)該是
????有2種方法。
- 再包裹一層div,讓外層div寬度為50%,然后讓內(nèi)層div有一個10px邊框,由于內(nèi)層div沒有是個塊級元素所以寬度會默認(rèn)撐滿父元素。代碼如下
- 另一種方法是使用css3的計(jì)算屬性calc(),將div的寬度設(shè)為50% - 20px,但是這個屬性兼容性一般。代碼如下 div{ width: calc(50% - 20px); border: 10px solid black; } ….顯然,IE盒模型的實(shí)現(xiàn)方案更加簡潔和直觀。后來W3C也意識到了這個問題 于是為了重新支持IE盒模型,W3C組織在CSS3中添加了box-sizing屬性,用于讓開發(fā)者可以隨意切換這兩種盒模型。
二、元素的分類
2.1 塊級元素 & 行內(nèi)元素 & 行內(nèi)塊級元素
元素除了自己的盒模型外還有自己的分類。從元素的布局特性來分,主要可以分為三類元素:
塊級元素,行內(nèi)元素,行內(nèi)塊級元素。我們現(xiàn)在看下他們的定義:
塊級元素:display屬性取block、table、flex、grid和list-item的元素。
行內(nèi)級元素:display屬性取inline的元素。
行內(nèi)塊級元素:display屬性取inline-block、inline-table、inline-flex和inline-grid的元素
很多網(wǎng)上或者書上說: div是個塊級元素,span是個行內(nèi)元素。這樣的說法是不正確的,或者說是不嚴(yán)謹(jǐn)?shù)摹N覀冎荒苷fdiv默認(rèn)是個塊級元素,span默認(rèn)是個行內(nèi)元素。就是因?yàn)槊總€元素初始都會帶有一些樣式屬性,而div默認(rèn)的display是block,span的display是inline。但是如果我們在css中去設(shè)置他們的display屬性就可以改變他們的類型。
接下來我們看看他們都有什么特點(diǎn),很簡單
塊級元素
行內(nèi)元素
行內(nèi)塊級元素( 結(jié)合了塊級元素和行內(nèi)元素的特征 )
對于塊級元素很簡單,沒有什么可說的。就是一點(diǎn),無論我們把塊級元素的寬度設(shè)置多小,他們也只能在一行里單獨(dú)顯示,而不會跟這個元素的兄弟元素在同一行顯現(xiàn)。
對于行內(nèi)或者行內(nèi)塊級元素來說,有個小注意點(diǎn)。當(dāng)有多個這樣的元素并排排列時 你會發(fā)現(xiàn)他們之間是有
幾像素的間距的,我們來看下面的代碼 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style> span{ background: blue; } </style> </head> <body><div><span>LearnInPro1</span><span>LearnInPro2</span><span>LearnInPro3</span></div> </body> </html>我們會發(fā)現(xiàn) 他們之間會有間距 像這樣:
這是由于我們?yōu)榱舜a的整潔和直觀,一般把每個標(biāo)簽在單獨(dú)一行里書寫,這樣就造成了,標(biāo)簽之間會存在換行符,在渲染過程中,渲染引擎會認(rèn)為換行符是一種文本,所以導(dǎo)致了我們每個span之間就跟存在著一個空格一樣。
那么我們這里介紹兩個方法來消除這個間距
?
2.2 行框
關(guān)于元素分類,我們再來講一個概念,叫做
行框。我們現(xiàn)在看下行框的概念:子元素的虛擬矩形區(qū)域,形成的每一行。這個概念有點(diǎn)抽象,我們結(jié)合下面這張圖來理解下。
我們可以看到,
- 當(dāng)行內(nèi)元素或者行內(nèi)塊級元素并排排列的時候,可能他們的字體大小,高度都是不一樣的。那么行框就是包裹他們的一個框。就是圖中Line box所指的區(qū)域。
- 行框規(guī)定了這些元素排列時候的對齊方式。默認(rèn)他們的對齊方式是根據(jù)baseline基準(zhǔn)線對齊。就如同圖上的對齊方式一樣。
- 在行框中,我們利用vertical-align來改變他們的對齊方式。他的值有很多,常用的有top,middle,bottom等,這個比較簡單就不多介紹了。
要特別注意的點(diǎn)有兩個
- 首先,文本的高度是跟line-height無關(guān)的。我們可以給span設(shè)置一個背景色,然后我們改變他的line-height會發(fā)現(xiàn),無論line-height設(shè)置成多高,span的背景色的高度都不會改變,但是span整體的高度會隨line-height的增大而變高。所以說文本的高度是跟line-height無關(guān)的(注意這里說的是文本)。
- 那么,文本的高度只跟font-size有關(guān),但是注意,文本的高度永遠(yuǎn)會大于font-size的值。就像下面這張圖,font-size的大小只是規(guī)定了text-top到text-bottom的距離,而文本高度是top到bottom的距離,而這之間的距離是多少,每個瀏覽器都不太一樣。總之是為了保護(hù)文本,不希望行與行之間產(chǎn)生重疊。( 如果你強(qiáng)行將line-height設(shè)置的特別小,希望產(chǎn)生重疊,在大部分現(xiàn)代瀏覽器中是無效的,也就是在大部分瀏覽器中l(wèi)ine-height的值最小等于文本的高度,所以不建議將line-height設(shè)的比文本高度小。 )
- 所以,行內(nèi)元素的高度(不折行的情況下)當(dāng)沒設(shè)置line-height或者line-height小于等于文本的內(nèi)容高度時,行內(nèi)元素高度取決于font-size,等于文本的高度。 當(dāng)line-height大于文本高度時,則由line-height決定。
?
2. 當(dāng)行內(nèi)元素和行內(nèi)塊級元素在一個行框內(nèi)排列的時候,比如:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style> *{ margin: 0; padding: 0; } span{ background: blue; font-size: 20px; } .inline-block{ height: 100px; width: 100px; background: red; display: inline-block; } </style> </head> <body> <div style="background: gray;"><span>LearnInPro</span><div class="inline-block"></div></div> </body> </html>就會變成下圖這樣
我們前面說過 這兩個元素中間的空隙是由于換行符導(dǎo)致的,并且也介紹了解決方案,而這次要說的是這個紅色的行內(nèi)塊級元素下方的空隙,這個就是由于行框默認(rèn)的對齊方式導(dǎo)致的。由于行框默認(rèn)是baseline對齊,行內(nèi)塊級元素也要遵守所以這個紅框的底部會騎在baseline線上。導(dǎo)致baseline到bottom的區(qū)域空著,產(chǎn)生空隙。那么解決方案也很簡單,只要改變行框的對齊方式,在這兩個元素上都加上
vertical-align: top || middle || bottom 等就可以把這個空隙消除掉。由于css布局相關(guān)知識,比較重要,知識點(diǎn)也比較多。我們下篇文章再來介紹其他的部分。
?
最后你覺得我們的文章對你有幫助,歡迎關(guān)注我們的 微信公眾號LearnInPro,在上面你可以第一時間獲取到我們的技術(shù)文章,并且你可以隨時在上面向我們提問,把你在學(xué)習(xí)前端過程中所遇到的問題發(fā)給我們。我們每天都會按時回復(fù)大家的每一個問題,希望
LearnInPro可以伴隨你從入門到專家。 ??
?
總結(jié)
以上是生活随笔為你收集整理的深入css布局 (1) — 盒模型 元素分类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS节选——选择器
- 下一篇: 移动端页面字体在微信被放大,导致排版错乱