深入css佈局(1)— 盒模型 & 元素分類

来源:https://www.cnblogs.com/learninpro/archive/2018/05/19/9061512.html
-Advertisement-
Play Games

深入css佈局(1)—— 盒模型 & 元素分類 “ 在css知識體系中,除了css選擇器,樣式屬性等基礎知識外,css佈局相關的知識才是css比較核心和重要的點。今天我們來深入學習一下css佈局相關的知識。” 首先來列下大綱 盒模型 IE盒模型 W3C盒模型 box-sizing 元素的分類 塊級元 ...


 

深入css佈局(1)—— 盒模型 & 元素分類

 

    “ 在css知識體系中,除了css選擇器,樣式屬性等基礎知識外,css佈局相關的知識才是css比較核心和重要的點。今天我們來深入學習一下css佈局相關的知識。”

 

首先來列下大綱

  • 盒模型
    • IE盒模型
    • W3C盒模型
    • box-sizing
  • 元素的分類
    • 塊級元素
    • 行內元素
    • 行內塊級元素
    • 行框
  • 定位與浮動
    • 文檔流
    • 包含塊
    • 浮動清除
  • margin問題
  • 格式化上下文(formatting context)
    • BFC、IFC、FFC、GFC
  • 常見佈局實戰
    • 水平垂直居中
    • 兩欄 & 三欄佈局


一、css盒模型

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標準盒模型。

我們來看下麵這張圖

 

在圖的上半部分中展示的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種方法。

  • 再包裹一層div,讓外層div寬度為50%,然後讓內層div有一個10px邊框,由於內層div沒有是個塊級元素所以寬度會預設撐滿父元素。代碼如下
<!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>
  • 另一種方法是使用css3的計算屬性calc(),將div的寬度設為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屬性就可以改變他們的類型。

接下來我們看看他們都有什麼特點,很簡單

塊級元素

  1. 獨占一行顯示(width預設為100%,height為0);
  2. 可以設置尺寸屬性(width、height等);

行內元素

  1. 一行可以顯示多個;
  2. 不能設置寬高或者說設置的width,height無效;
  3. 受父元素的text-align屬性和自身vertical-align屬性的控制,在水平方向上預設左對齊,在垂直方向上預設在行框的baseline基線上顯示(“行框”的概念,會在後面深入講解)

行內塊級元素( 結合了塊級元素和行內元素的特征 )

  1. 一行可以顯示多個;
  2. 可以設置尺寸屬性(width、height等);
  3. 受父元素的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之間就跟存在著一個空格一樣。

那麼我們這裡介紹兩個方法來消除這個間距

  1. 很簡單,我們直接把span在一行里書寫就好了,像這樣:
<div>
    <span>LearnInPro1</span><span>LearnInPro2</span><span>LearnInPro3</span>
</div>
  1. 由於渲染引擎認為換行符是一種文本,那我把文本的font-size設為0不就可以了麽。

註意:由於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等,這個比較簡單就不多介紹了。

要特別註意的點有兩個

  1. 我們說過行內元素是不能設置高度的,那麼他的高度是如何決定的呢? 任何一個行內元素,他的高度是由font-size和line-height共同決定的。
  • 首先,文本的高度是跟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決定。

 

 2. 當行內元素和行內塊級元素在一個行框內排列的時候,比如:

<!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可以伴隨你從入門到專家。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 群集準備工作 個人電腦 記憶體12G,處理器 AMD A6-3650CPU主頻2.6GHz 虛擬機 VMware Workstation 12 資料庫 sql server 2008 r2 三台虛擬伺服器 windows server 2008 r2 enterprise , 記憶體分配2g,使用網路橋 ...
  • MySQL不允許遠程登錄,所以遠程登錄失敗了,解決方法如下: 執行FLUSH PRIVILEGES; ...
  • AIDL:Android Interface Definition Language,即 Android 介面定義語言。 AIDL 是什麼 Android 系統中的進程之間不能共用記憶體,因此,需要提供一些機制在不同進程之間進行數據通信。 為了使其他的應用程式也可以訪問本應用程式提供的服務,Andro ...
  • Github地址 第一步:初始化我們的工具類 第二步,直接調用使用嘍,就是這麼簡單粗暴 RegistGetVCodeBean 本文出處:https://blog.csdn.net/easkshark/article/details/62897368 ...
  • NSSortDescriptor 排序 Person類 1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 5 @property (nonatomic, copy) NSString *name; 6 @pr ...
  • 一、todolist功能開發 <div id="root"> <div> <input type="text" v-model="inputValue"> <button @click="handleSubmit">提交</button> </div> <ul> <li v-for="(item, ...
  • 今天終於能更新博文了……(確實有些不應該,5月份到現在就沒認認真真寫過幾行代碼) 今天算是正式在學Vue.js了,前期想必大家也能看得出來,我為那個即時通訊系統寫的代碼註釋,基本上都是自己在胡亂猜測的,很隨意很隨性的在寫註釋(可能都完全不正確…) 今天簡單的抄寫了兩個官網上的例子,花了半個小時左右的 ...
  • 前言 我的目標是寫一個非常詳細的關於diff的乾貨,所以本文有點長。也會用到大量的圖片以及代碼舉例,目的讓看這篇文章的朋友一定弄明白diff的邊邊角角。 先來瞭解幾個點... 1. 當數據發生變化時,vue是怎麼更新節點的? 要知道渲染真實DOM的開銷是很大的,比如有時候我們修改了某個數據,如果直接 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...