在css知識體系中,除了css選擇器,樣式屬性等基礎知識外,css佈局相關的知識才是css比較核心和重要的點。今天咱們來深刻學習一下css佈局相關的知識。
盒模型css
- IE盒模型
- W3C盒模型
- box-sizing
元素的分類html
- 塊級元素
- 行內元素
- 行內塊級元素
- 行框
定位與浮動前端
- 文檔流
- 包含塊
- 浮動清除
- margin問題
**格式化上下文(formatting context)css3
- BFC、IFC、FFC、GFC
常見佈局實戰瀏覽器
- 水平垂直居中
- 兩欄 & 三欄佈局
- ...
1.1 IE盒模型與W3C盒模型
首先你們都知道一個頁面是由衆多HTML元素組成的,每個元素都有本身的一個矩形的顯示區域,這就是咱們平時常常說起的css盒模型。微信
這個盒模型或者說這個矩形的顯示區域呢 就是向下面這張圖同樣,包括四部分:佈局
margin(外邊距)+border(邊框)+padding(內邊距)+content(內容)
在css的發展歷程中,有兩種版本的盒模型,一個叫IE盒模型
(又叫怪異盒模型),一個叫W3C標準盒模型
,在早期的微軟出的IE瀏覽器中採用的是本身的盒模型標準成爲IE盒模型或者叫怪異盒模型。學習
規定:元素width和height屬性是包含元素的border(邊框)+padding(內邊距)+content(內容)的。
然後來W3C組織(中文叫作萬維網聯盟,是一家中立性的技術標準指定機構),一個專門制定互聯網技術標準的機構,爲了標準化前端的技術規範,他規定了個標準稱爲W3C標準盒模型。字體
規定:元素width和height屬性只包含元素的content(內容)。
後來微軟也慢慢轉向了W3C的標準,在IE6之後支持了W3C標準盒模型。在咱們如今的主流瀏覽器裏面默認都是使用w3c標準盒模型。flex
咱們來看下面這張圖
在圖的上半部分中展現的W3C盒模型標準,好比我聲明一個div的width屬性爲100px,那我只是規定了這個div的content內容顯示區域的大小爲100px,若是以後我再聲明div的padding爲10px, border爲15px solid black, 那麼這個div最終的總體寬度就會變成 100 + 10 * 2 + 15 * 2 = 150px
了。
而若是一樣的css運用到了IE盒模型身上那麼當我規定div的width屬性爲100px時,他總體的寬度就已經肯定了,就是100px,再以後我去聲明div的padding爲10px,border爲15px solid black,也不會影響我這個div的總體寬度,只是會壓縮這個div的content內容顯示區域的大小。
<!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幹嗎用的?
咱們剛在說道目前主流瀏覽器默認都是採用W3C盒模型,若是你就是想在這些瀏覽器裏使用IE盒模型呢?你就須要使用box-sizing這個屬性,這是個css3中新出的屬性:默認值是content-box就是指的使用W3C盒模型標準,另一個值是border-box,指的就是我要在這個元素上使用IE盒模型標準。
#div1 { box-sizing: border-box || content-box(默認值) }
那麼這裏就有個問題了,爲啥W3C組織好不容易將IE盒模型摒棄調,統一了前端這個盒模型標準並且全部瀏覽器廠商也都默認支持了,如今反而在css3中加入了box-sizing屬性讓咱們能夠自由選擇盒模型標準了呢?
答案就是W3C忽然發如今某些狀況下,IE盒模型比本身家的那個盒模型標準更好用。 =。=...(這就很尷尬了...) 因而在css3中加入了box-sizing這個屬性讓開發者能夠自由選擇要使用哪一種標準(估計是被噴慘了...)
咱們來看這樣一個例子:若是如今咱們要實現這樣一個簡單佈局,我要一個div的總體寬度是頁面的50%,而且呢這個div還帶有一個10px的邊框。咱們要怎麼作呢?
若是咱們用IE盒模型標準的話就很簡單
div{ width: 50%; border: 10px solid black; box-sizing: border-box; /* 設置爲IE盒模型標準 */ }
就能夠了 是吧。
那麼若是咱們使用W3C盒模型呢。
咱們知道若是咱們聲明這個div寬度爲50%,而後聲明border爲10px的話 那麼這個div實際寬度應該是50% + 20px
對吧 因此這樣不符合咱們的要求,那麼要怎麼作呢。
有2種方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #div1{ width: 50%; } #div1{ border: 10px solid black; } </style> </head> <body> <div id="div1"> <div id="div2"></div> </div> </body> </html>
50% - 20px
,可是這個屬性兼容性通常。代碼以下div{ width: calc(50% - 20px); border: 10px solid black; }
....顯然,IE盒模型的實現方案更加簡潔和直觀。後來W3C也意識到了這個問題 因而爲了從新支持IE盒模型,W3C組織在CSS3中添加了box-sizing屬性,用於讓開發者能夠隨意切換這兩種盒模型。
2.1 塊級元素 & 行內元素 & 行內塊級元素
元素除了本身的盒模型外還有本身的分類。從元素的佈局特性來分,主要能夠分爲三類元素:塊級元素
,行內元素
,行內塊級元素
。
咱們如今看下他們的定義:
塊級元素:display屬性取block、table、flex、grid和list-item的元素。
行內級元素:display屬性取inline的元素。
行內塊級元素:display屬性取inline-block、inline-table、inline-flex和inline-grid的元素
不少網上或者書上說: div是個塊級元素,span是個行內元素。這樣的說法是不正確的,或者說是不嚴謹的。咱們只能說div默認是個塊級元素,span默認是個行內元素。就是由於每一個元素初始都會帶有一些樣式屬性,而div默認的display是block,span的display是inline。可是若是咱們在css中去設置他們的display屬性就能夠改變他們的類型。
接下來咱們看看他們都有什麼特色,很簡單
塊級元素
- 獨佔一行顯示(width默認爲100%,height爲0);
- 能夠設置尺寸屬性(width、height等);
行內元素
- 一行能夠顯示多個;
- 不能設置寬高或者說設置的width,height無效;
- 受父元素的text-align屬性和自身vertical-align屬性的控制,在水平方向上默認左對齊,在垂直方向上默認在行框的baseline基線上顯示(「行框」的概念,會在後面深刻講解)
行內塊級元素( 結合了塊級元素和行內元素的特徵 )
- 一行能夠顯示多個;
- 能夠設置尺寸屬性(width、height等);
- 受父元素的text-align屬性和自身vertical-align屬性的控制
對於塊級元素很簡單,沒有什麼可說的。就是一點,不管咱們把塊級元素的寬度設置多小,他們也只能在一行裏單獨顯示,而不會跟這個元素的兄弟元素在同一行顯現。
對於行內或者行內塊級元素來講,有個小注意點。當有多個這樣的元素並排排列時 你會發現他們之間是有幾像素的間距
的,咱們來看下面的代碼
<!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>
咱們會發現 他們之間會有間距 像這樣:
這是因爲咱們爲了代碼的整潔和直觀,通常把每一個標籤在單獨一行裏書寫,這樣就形成了,標籤之間會存在換行符,在渲染過程當中,渲染引擎會認爲換行符是一種文本,因此致使了咱們每一個span之間就跟存在着一個空格同樣。
那麼咱們這裏介紹兩個方法來消除這個間距
<div> <span>LearnInPro1</span><span>LearnInPro2</span><span>LearnInPro3</span> </div>
注意:因爲font-size屬性是一個可繼承屬性,因此在div上將font-size設爲0後還須要再span上把font-size設回來,不然span裏的文本的font-size也會變成0。像這樣:
div { font-size: 0; } span{ font-size: 16px; background: blue; }
2.2 行框
關於元素分類,咱們再來說一個概念,叫作行框
。
咱們如今看下行框的概念:子元素的虛擬矩形區域,造成的每一行。這個概念有點抽象,咱們結合下面這張圖來理解下。
咱們能夠看到,
- 當行內元素或者行內塊級元素並排排列的時候,可能他們的字體大小,高度都是不同的。那麼行框就是包裹他們的一個框。就是圖中Line box所指的區域。
- 行框規定了這些元素排列時候的對齊方式。默認他們的對齊方式是根據baseline基準線對齊。就如同圖上的對齊方式同樣。
- 在行框中,咱們利用vertical-align來改變他們的對齊方式。他的值有不少,經常使用的有top,middle,bottom等,這個比較簡單就很少介紹了。
要特別注意的點有兩個
首先,文本的高度是跟line-height無關的。咱們能夠給span設置一個背景色,而後咱們改變他的line-height會發現,不管line-height設置成多高,span的背景色的高度都不會改變,可是span總體的高度會隨line-height的增大而變高。因此說文本的高度是跟line-height無關的(注意這裏說的是文本)。
- 那麼,文本的高度只跟font-size有關,可是注意,文本的高度永遠會大於font-size的值,就像下面這張圖。font-size的大小隻是規定了text-top到text-bottom的距離,而文本高度是top到bottom的距離,而這之間的距離是多少,每一個瀏覽器都不太同樣。總之是爲了保護文本,不但願行與行之間產生重疊。( 若是你強行將line-height設置的特別小,但願產生重疊,在大部分現代瀏覽器中是無效的,也就是在大部分瀏覽器中line-height的值最小等於文本的高度,因此不建議將line-height設的比文本高度小。 )
- 因此,行內元素的高度(不折行的狀況下)當沒設置line-height或者line-height小於等於文本的內容高度時,行內元素高度取決於font-size,等於文本的高度。 當line-height大於文本高度時,則由line-height決定。
<!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>
就會變成下圖這樣
咱們前面說過 這兩個元素中間的空隙是因爲換行符致使的,而且也介紹瞭解決方案,而此次要說的是這個紅色的行內塊級元素下方的空隙,這個就是因爲行框默認的對齊方式致使的。因爲行框默認是baseline對齊,行內塊級元素也要遵照因此這個紅框的底部會騎在baseline線上。致使baseline到bottom的區域空着,產生空隙。那麼解決方案也很簡單,只要改變行框的對齊方式,在這兩個元素上都加上vertical-align: top || middle || bottom
等就能夠把這個空隙消除掉。
因爲css佈局相關知識,比較重要,知識點也比較多。咱們下篇文章再來介紹其餘的知識點。
最後你以爲咱們的文章對你有幫助,歡迎關注咱們的
微信公衆號LearnInPro,在上面你能夠第一時間獲取到咱們的技術文章,而且你能夠隨時在上面向咱們提問,把你在學習前端過程當中所遇到的問題發給咱們。咱們天天都會按時回覆你們的每個問題,但願
LearnInPro
能夠伴隨你從入門到專家。