1. 程式人生 > 其它 >轉 前端面試HTML和CSS總結 前端面試HTML和CSS總結,這一篇就夠了!

轉 前端面試HTML和CSS總結 前端面試HTML和CSS總結,這一篇就夠了!

轉   自己寫點東西出來你。看知識。

六扇有伊人

-取消關注 

園齡:3年5個月粉絲:12關注:1

前端面試HTML和CSS總結,這一篇就夠了!

一,面試基礎 HTML和CSS

ps:這倆面試答不上來的,基本就可以回去了,以下是HTML題,一般來說這地方不會出太多題,面試官也不願意花太多時間在這上面。

1,HTML語義化,如何理解語義化?

讓人更容易懂(增加程式碼的可讀性)

讓搜尋引擎更容易懂,有利於爬蟲抓取

在沒有css的情況下,頁面也能更好的展現出其內容結構,程式碼·結構

2,script 標籤中 defer 和 async 的區別?

script:會阻礙HTML解析,只有下載好並執行完指令碼才會繼續解析HTML

async:解析HTML的過程中會非同步下載指令碼,下載成功後立即執行,可能會阻斷HTML的解析

defer:完全不會阻斷HTML解析,解析完成之後在按順序執行指令碼

圖解 script 標籤中的 async 和 defer 屬性

3,從瀏覽器位址列輸入 url 到請求返回發生了什麼

3.1,輸入url之後,會解析出主機,埠,路徑,協議等資訊,構造一個HTTP請求

3.2,DNS域名解析

3.3,TCP連結,http請求

3.4,伺服器處理請求並返回HTTP報文

3.5,瀏覽器渲染(HTML解析,css解析,js解析,render樹)

推文:從輸入 URL 開始建立前端知識體系

推文:從 URL 輸入到頁面展現到底發生什麼

推文:位元組面試被虐後,是時候搞懂 DNS 了

從上到下依次閱讀

4,HTTP和HTTPS的區別

http:

      • 不安全
      • 協議對客戶端沒有狀態儲存【沒有狀態】
      • 每次請求需要TCP三次握手四次揮手,和伺服器重新建立連線【沒有連線】
      • 基本的特性,由客戶端發起請求,服務端響應
      • 簡單快速、靈活
      • 使用明文、請求和響應不進行確認

https:

      • 安全
      • HTTP安全版本,通過SSL或TLS提供加密處理資料、驗證對方身份以及資料完整性保護
      • 採用混合加密技術,傳輸過程無法直接檢視明文內容【傳輸加密】
      • 通過證書認證客戶端訪問的是自己的伺服器【身份認證】
      • 傳輸過程防止被篡改【資料完整】

ps:以下是css的面試題,打不出來的話可能會有非常不好的印象

5,css盒子模型的介紹

css3中盒子模型有兩種,一種是W3C標準盒子模型,一種是IE盒子模型

兩種盒子模型都是由content,margin,padding,border構成,其大小都是由content,padding,border決定的,但是盒子內容卻有所不同:

      • 標準盒模型:只包含 content 。
      • IE(替代)盒模型:content + padding + border 。

可以通過 box-sizing 來改變元素的盒模型:

      • box-sizing: content-box :標準盒模型(預設值)。
      • box-sizing: border-box :IE(替代)盒模型。

6,css選擇器

選擇器 權重 使用示例
!important 1111 * {color: '#00f' !important}
行內 1000 <span style={color:'#00f'} />
id 0100 #id{color:'#00f}
class 0010 .calssName{color:'#00f}
標籤 0001 div{color:'#00f}
子選擇 0001 div > span{color:'#00f}
偽類 0001 a:hover {color:'#00f}>

優先順序的計算規則:

相信每位寫過CSS的朋友都知道,CSS選擇器的優先順序關係是:  內聯 > ID選擇器 > 類選擇器 > 標籤選擇器

但是,瀏覽器具體的優先順序演算法是怎樣的?可能還有些人不知道 。《CSS REFACTORING》 中提到了演算法的過程 

1 2 3 4 5 6 A specificity is determined by plugging numbers into (a, b, c, d):   If the styles are applied via the style attribute, a=1; otherwise, a=0. is equal to the number of ID selectors present. is equal to the number of class selectors, attribute selectors, and pseudoclasses present. is equal to the number of type selectors and pseudoelements present.

  簡單來說就是通過,A,B,C,D四個值來確定,具體的規則如下:

如果存在內聯樣式,那麼 A = 1,否則 A = 0 ;
B 的值等於 ID選擇器(#id) 出現的次數;
C 的值等於 類選擇器(.class) 和 屬性選擇器(a[href="https://example.org"]) 和 偽類(:first-child) 出現的總次數;
D 的值等於 標籤選擇器(h1,a,div) 和 偽元素(::before,::after) 出現的總次數。

而比較規則是: 從左往右依次進行比較 ,較大者勝出,如果相等,則繼續往右移動一位進行比較 。如果4位全部相等,則後面的會覆蓋前面的

舉個栗子:

<div class="nav-list" id="nav-list">
    <div class="item">nav1</div>
    <div class="item">nav2</div>
</div>

#nav-list .item {
    color: #f00;
}

.nav-list .item {
    color: #0f0;
}

上邊程式碼,算出 #nav-list .item 的優先順序是(0,1,1,0) 算出 .nav-list .item  的優先順序是(0,0,2,0)

首先比較第一位都是0,相等,往右邊找第二位,#nav-list .item的優先順序第二位是1,.nav-list .item 優先順序的第二位是0,所以#nav-list .item的優先順序大於.nav-list .item 

推薦:深入理解 CSS 選擇器優先順序

7,重排(reflow)和重繪(repaint)的區別

兩種概念:

      • 重排:無論通過什麼方式影響了元素的幾何資訊(元素在視口內的位置和尺寸大小),瀏覽器需要重新計算元素在視口內的幾何屬性,這個過程叫做重排。
      • 重繪::通過構造渲染樹和重排(迴流)階段,我們知道了哪些節點是可見的,以及可見節點的樣式和具體的幾何資訊(元素在視口內的位置和尺寸大小),接下來就可以將渲染樹的每個節點都轉換為螢幕上的實際畫素,這個階段就叫做重繪。

 如何減少重排和重繪

最小化重繪和重排,比如樣式集中改變,使用新增新樣式類名 .class 或 cssText

批量操作 DOM,比如讀取某元素 offsetWidth 屬性存到一個臨時變數,再去使用,而不是頻繁使用這個計算屬性;又比如利用 document.createDocumentFragment() 來新增要被新增的節點,處理完之後再插入到實際 DOM 中

使用 **absolute** 或 **fixed** 使元素脫離文件流,這在製作複雜的動畫時對效能的影響比較明顯

開啟 GPU 加速,利用 css 屬性 transform 、will-change 等,比如改變元素位置,我們使用 translate 會比使用絕對定位改變其 left 、top 等來的高效,因為它不會觸發重排或重繪,transform 使瀏覽器為元素建立⼀個 GPU 圖層,這使得動畫元素在一個獨立的層中進行渲染。當元素的內容沒有發生改變,就沒有必要進行重繪作者:vortesnail

瀏覽器渲染的過程

  1. 解析HTML生成DOM樹,解析CSS生成CSSOM樹
  2. 將DOM樹和CSSOM樹結合,生成渲染樹(Render Tree)
  3. Layout(迴流):根據生成的渲染樹,進行迴流(Layout),得到節點的幾何資訊(位置,大小)
  4. Painting(重繪):根據渲染樹以及迴流得到的幾何資訊,得到節點的絕對畫素
  5. Display:將像素髮送給GPU,展示在頁面上。
 

為了構建渲染樹,瀏覽器主要完成了以下工作:

  1. 從DOM樹的根部開始遍歷出每個可見的節點 (不可見的節點有:script、meta、link等。還有一些通過css進行隱藏的節點。比如display:none)
  2. 對每個可見的節點,找到CSSOM樹上對應的規則,並應用他們
  3. 根據每個可見節點以及其對應的樣式,組合生成渲染樹

注意:渲染樹只包含可見的節點

注意,利用visibility和opacity隱藏的節點,還是會顯示在渲染樹上的。只有display:none的節點才不會顯示在渲染樹上

從上邊的例子我們可以看到span標籤的樣式有一個display:none,它最終並沒有在渲染樹上

迴流(Layout)

我們通過構造渲染樹,將可見DOM節點以及它對應的樣式結合起來,可是我們還需要計算它們在裝置視口(viewport)內的確切位置和大小,這個計算的階段就是迴流

為了弄清每個物件在網站上的確切大小和位置,瀏覽器從渲染樹的根節點開始遍歷,舉個栗子:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Critial Path: Hello world!</title>
  </head>
  <body>
    <div style="width: 50%">
      <div style="width: 50%">Hello world!</div>
    </div>
  </body>
</html>

我們可以看到,第一個div將節點的顯示尺寸設定為視口寬度的50%,第二個div將其尺寸設定為父節點的50%

而在迴流這個階段,我們就需要根據視口具體的寬度,將其轉為實際的畫素值

重繪(Painting)

最終,我們通過構造渲染樹和迴流階段,知道了那些元素是可見的,以及可見節點的樣式和具體的幾何影象資訊(也就是在頁面上的位置,大小)那麼我們就可以將渲染樹的每個節點都轉換為螢幕上的實際畫素,這個階段就叫做重繪節點

何時會發生迴流重繪?

既然前邊我們都知道了,迴流這一階段主要是計算節點的位置和幾何資訊,那麼當頁面佈局和幾何資訊發生變化的時候,就需要回流。舉幾個栗子:

        • 新增或刪除可見的DOM元素
        • 元素的位置發生變化
        • 元素的尺寸發生變化(包括外邊距、內邊框、邊框大小、高度和寬度等)
        • 內容發生變化,比如文字變化或圖片被另一個不同尺寸的圖片所替代。
        • 頁面一開始渲染的時候(這肯定避免不了)
        • 瀏覽器的視窗尺寸變化(因為迴流是根據視口的大小來計算元素的位置和大小的)

注意:迴流一定會觸發重繪,而重繪不一定會迴流

根據改變的範圍和程度,渲染樹中或大或小的部分需要重新計算,有些改變會觸發整個頁面的重排,比如,滾動條出現的時候或者修改了根節點

推薦騰訊 IVWEB 團隊的這篇文章:你真的瞭解迴流和重繪嗎

8,對BFC的理解

全程 block format contex 塊級格式上下文,就是一塊獨立渲染區域,不影響文件流

建立 BFC 的方式:

      • 絕對定位元素(position 為 absolute 或 fixed )。
      • 行內塊元素,即 display 為 inline-block 。
      • overflow 的值不為 visible 。

推薦文章:可能是最好的 BFC 解析了...

9,實現兩欄佈局(左側固定,右側自適應)

DOM結構:

<div class="outer">
  <div class="left">左側</div>
  <div class="right">右側</div>
</div>

方法一:

利用浮動,左邊元素寬度固定,右邊元素的margin-left固定,注意:右邊元素的width是auto,跟隨父級自動撐滿

.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  margin-left: 200px;
  height: 100%;
  background: lightseagreen;
}

方法二:

同樣利用浮動,將左邊元素寬度固定,然後給右邊元素加上overflow:hidden,這樣就觸發了 BFC ,BFC的區域不會與浮動元素髮生重疊,所以兩側就不會發生重疊

.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  overflow: hidden;
  height: 100%;
  background: lightseagreen;
}

方法三:

利用 flex佈局,左邊元素固定寬度,右邊的元素設定  flex: 1

.outer {
  display: flex;
  height: 100px;
}
.left {
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  flex: 1;
  height: 100%;
  background: lightseagreen;
}

方法四:

利用定位,給父級元素相對定位,給左邊元素絕對定位,固定左邊元素的寬度,右邊元素margin-left 留出位置

.outer {
  position: relative;
  height: 100px;
}
.left {
  position: absolute;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  margin-left: 200px;
  height: 100%;
  background: lightseagreen;
}

方法五:

也是定位,給右邊元素絕對定位,給父級相對定位,然後固定左邊元素的寬度,給右邊元素設定 left 留出位置,剩餘的全為0

.outer { position: relative; height: 100px; }
.left { width: 200px; height: 100%; background: lightcoral; }
.right { position: absolute; left: 200px; top: 0; right: 0; bottom: 0; height: 100%; background: lightseagreen; }

10,實現聖盃佈局和雙飛翼佈局(經典的三欄佈局)

詢問聖盃佈局和雙飛翼佈局的目的:

  • 三欄佈局,中間的內容一定要優先渲染(內容最重要)
  • 兩邊固定,中間的隨著頁面自適應
  • 用於pc端頁面

技術總結:

  • 使用 float 佈局
  • 兩側使用 margin 負值,以便和中間內容橫向重疊
  • 防止中間內容被兩側覆蓋,聖盃佈局用 padding ,雙飛翼佈局用 margin

聖盃佈局:

<div id="container" class="clearfix">
  <p class="center">我是中間</p>
  <p class="left">我是左邊</p>
  <p class="right">我是右邊</p>
</div>

css樣式:

#container {
  padding-left: 200px;
  padding-right: 150px;
  overflow: auto;
}
#container p {
  float: left;
}
.center {
  width: 100%;
  background-color: lightcoral;
}
.left {
  width: 200px;
  position: relative;
  left: -200px;
  margin-left: -100%;
  background-color: lightcyan;
}
.right {
  width: 150px;
  margin-right: -150px;
  background-color: lightgreen;
}
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}

雙飛翼佈局:

<div id="main" class="float">
  <div id="main-wrap">main</div>
</div>
<div id="left" class="float">left</div>
<div id="right" class="float">right</div>

css樣式:

.float {
  float: left;
}
#main {
  width: 100%;
  height: 200px;
  background-color: lightpink;
}
#main-wrap {
  margin: 0 190px 0 190px;
}
#left {
  width: 190px;
  height: 200px;
  background-color: lightsalmon;
  margin-left: -100%;
}
#right {
  width: 190px;
  height: 200px;
  background-color: lightskyblue;
  margin-left: -190px;
}

11,水平垂直居中

方法一:flex 佈局

.box{
  display: flex;
  justify-content: center;
  align-items: center;
}

方法二:利用絕對定位,left:50% top:50% 然後再通過  margin-left  和 margin-top 設定負值實現

.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 200px;
  margin-left: -100px;
  margin-top: -100px;
}

方法三:和上邊的方法差不多,但用了css3新增的屬性 translate 來實現

.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

方法四:利用絕對定位,子元素所有方向都為 0 ,將 margin  設定為 auto ,由於寬高固定,對應方向實現平分,注意:該方法必須盒子有寬高

.father {
  position: relative;
}
.son {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0px;
  margin: auto;
  height: 100px;
  width: 100px;
}

關於div居中的方法還有很多這裡推薦一篇:面試官:你能實現多少種水平垂直居中的佈局(定寬高和不定寬高)

12,flex佈局

Flex 是 Flexible Box 的縮寫,意為"彈性佈局",用來為盒狀模型提供最大的靈活性,任何一個容器都可以指定為 Flex 佈局

推薦閱讀:Flex 佈局教程 

13,line-height 如何繼承?

      • 父元素的 line-height 寫了具體數值,比如 30px,則子元素 line-height 繼承該值
      • 父元素的 line-height 寫了比例,比如 1.5 或 2,則子元素 line-height 也是繼承該比例
      • 父元素的 line-height 寫了百分比,比如 200%,則子元素 line-height 繼承的是父元素 font-size * 200% 計算出來的值

本文作者:六扇有伊人

本文連結:https://www.cnblogs.com/LiuSan/p/16857122.html

版權宣告:本作品採用知識共享署名-非商業性使用-禁止演繹 2.5 中國大陸許可協議進行許可。

一,面試基礎 HTML和CSS

ps:這倆面試答不上來的,基本就可以回去了,以下是HTML題,一般來說這地方不會出太多題,面試官也不願意花太多時間在這上面。

1,HTML語義化,如何理解語義化?

讓人更容易懂(增加程式碼的可讀性)

讓搜尋引擎更容易懂,有利於爬蟲抓取

在沒有css的情況下,頁面也能更好的展現出其內容結構,程式碼·結構

2,script 標籤中 defer 和 async 的區別?

script:會阻礙HTML解析,只有下載好並執行完指令碼才會繼續解析HTML

async:解析HTML的過程中會非同步下載指令碼,下載成功後立即執行,可能會阻斷HTML的解析

defer:完全不會阻斷HTML解析,解析完成之後在按順序執行指令碼

圖解 script 標籤中的 async 和 defer 屬性

3,從瀏覽器位址列輸入 url 到請求返回發生了什麼

3.1,輸入url之後,會解析出主機,埠,路徑,協議等資訊,構造一個HTTP請求

3.2,DNS域名解析

3.3,TCP連結,http請求

3.4,伺服器處理請求並返回HTTP報文

3.5,瀏覽器渲染(HTML解析,css解析,js解析,render樹)

推文:從輸入 URL 開始建立前端知識體系

推文:從 URL 輸入到頁面展現到底發生什麼

推文:位元組面試被虐後,是時候搞懂 DNS 了

從上到下依次閱讀

4,HTTP和HTTPS的區別

http:

      • 不安全
      • 協議對客戶端沒有狀態儲存【沒有狀態】
      • 每次請求需要TCP三次握手四次揮手,和伺服器重新建立連線【沒有連線】
      • 基本的特性,由客戶端發起請求,服務端響應
      • 簡單快速、靈活
      • 使用明文、請求和響應不進行確認

https:

      • 安全
      • HTTP安全版本,通過SSL或TLS提供加密處理資料、驗證對方身份以及資料完整性保護
      • 採用混合加密技術,傳輸過程無法直接檢視明文內容【傳輸加密】
      • 通過證書認證客戶端訪問的是自己的伺服器【身份認證】
      • 傳輸過程防止被篡改【資料完整】

ps:以下是css的面試題,打不出來的話可能會有非常不好的印象

5,css盒子模型的介紹

css3中盒子模型有兩種,一種是W3C標準盒子模型,一種是IE盒子模型

兩種盒子模型都是由content,margin,padding,border構成,其大小都是由content,padding,border決定的,但是盒子內容卻有所不同:

      • 標準盒模型:只包含 content 。
      • IE(替代)盒模型:content + padding + border 。

可以通過 box-sizing 來改變元素的盒模型:

      • box-sizing: content-box :標準盒模型(預設值)。
      • box-sizing: border-box :IE(替代)盒模型。

6,css選擇器

選擇器 權重 使用示例
!important 1111 * {color: '#00f' !important}
行內 1000 <span style={color:'#00f'} />
id 0100 #id{color:'#00f}
class 0010 .calssName{color:'#00f}
標籤 0001 div{color:'#00f}
子選擇 0001 div > span{color:'#00f}
偽類 0001 a:hover {color:'#00f}>

優先順序的計算規則:

相信每位寫過CSS的朋友都知道,CSS選擇器的優先順序關係是:  內聯 > ID選擇器 > 類選擇器 > 標籤選擇器

但是,瀏覽器具體的優先順序演算法是怎樣的?可能還有些人不知道 。《CSS REFACTORING》 中提到了演算法的過程 

1 2 3 4 5 6 A specificity is determined by plugging numbers into (a, b, c, d):   If the styles are applied via the style attribute, a=1; otherwise, a=0. is equal to the number of ID selectors present. is equal to the number of class selectors, attribute selectors, and pseudoclasses present. is equal to the number of type selectors and pseudoelements present.

  簡單來說就是通過,A,B,C,D四個值來確定,具體的規則如下:

如果存在內聯樣式,那麼 A = 1,否則 A = 0 ;
B 的值等於 ID選擇器(#id) 出現的次數;
C 的值等於 類選擇器(.class) 和 屬性選擇器(a[href="https://example.org"]) 和 偽類(:first-child) 出現的總次數;
D 的值等於 標籤選擇器(h1,a,div) 和 偽元素(::before,::after) 出現的總次數。

而比較規則是: 從左往右依次進行比較 ,較大者勝出,如果相等,則繼續往右移動一位進行比較 。如果4位全部相等,則後面的會覆蓋前面的

舉個栗子:

<div class="nav-list" id="nav-list">
    <div class="item">nav1</div>
    <div class="item">nav2</div>
</div>

#nav-list .item {
    color: #f00;
}

.nav-list .item {
    color: #0f0;
}

上邊程式碼,算出 #nav-list .item 的優先順序是(0,1,1,0) 算出 .nav-list .item  的優先順序是(0,0,2,0)

首先比較第一位都是0,相等,往右邊找第二位,#nav-list .item的優先順序第二位是1,.nav-list .item 優先順序的第二位是0,所以#nav-list .item的優先順序大於.nav-list .item 

推薦:深入理解 CSS 選擇器優先順序

7,重排(reflow)和重繪(repaint)的區別

兩種概念:

      • 重排:無論通過什麼方式影響了元素的幾何資訊(元素在視口內的位置和尺寸大小),瀏覽器需要重新計算元素在視口內的幾何屬性,這個過程叫做重排。
      • 重繪::通過構造渲染樹和重排(迴流)階段,我們知道了哪些節點是可見的,以及可見節點的樣式和具體的幾何資訊(元素在視口內的位置和尺寸大小),接下來就可以將渲染樹的每個節點都轉換為螢幕上的實際畫素,這個階段就叫做重繪。

 如何減少重排和重繪

最小化重繪和重排,比如樣式集中改變,使用新增新樣式類名 .class 或 cssText

批量操作 DOM,比如讀取某元素 offsetWidth 屬性存到一個臨時變數,再去使用,而不是頻繁使用這個計算屬性;又比如利用 document.createDocumentFragment() 來新增要被新增的節點,處理完之後再插入到實際 DOM 中

使用 **absolute** 或 **fixed** 使元素脫離文件流,這在製作複雜的動畫時對效能的影響比較明顯

開啟 GPU 加速,利用 css 屬性 transform 、will-change 等,比如改變元素位置,我們使用 translate 會比使用絕對定位改變其 left 、top 等來的高效,因為它不會觸發重排或重繪,transform 使瀏覽器為元素建立⼀個 GPU 圖層,這使得動畫元素在一個獨立的層中進行渲染。當元素的內容沒有發生改變,就沒有必要進行重繪作者:vortesnail

瀏覽器渲染的過程

  1. 解析HTML生成DOM樹,解析CSS生成CSSOM樹
  2. 將DOM樹和CSSOM樹結合,生成渲染樹(Render Tree)
  3. Layout(迴流):根據生成的渲染樹,進行迴流(Layout),得到節點的幾何資訊(位置,大小)
  4. Painting(重繪):根據渲染樹以及迴流得到的幾何資訊,得到節點的絕對畫素
  5. Display:將像素髮送給GPU,展示在頁面上。
 

為了構建渲染樹,瀏覽器主要完成了以下工作:

  1. 從DOM樹的根部開始遍歷出每個可見的節點 (不可見的節點有:script、meta、link等。還有一些通過css進行隱藏的節點。比如display:none)
  2. 對每個可見的節點,找到CSSOM樹上對應的規則,並應用他們
  3. 根據每個可見節點以及其對應的樣式,組合生成渲染樹

注意:渲染樹只包含可見的節點

注意,利用visibility和opacity隱藏的節點,還是會顯示在渲染樹上的。只有display:none的節點才不會顯示在渲染樹上

從上邊的例子我們可以看到span標籤的樣式有一個display:none,它最終並沒有在渲染樹上

迴流(Layout)

我們通過構造渲染樹,將可見DOM節點以及它對應的樣式結合起來,可是我們還需要計算它們在裝置視口(viewport)內的確切位置和大小,這個計算的階段就是迴流

為了弄清每個物件在網站上的確切大小和位置,瀏覽器從渲染樹的根節點開始遍歷,舉個栗子:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Critial Path: Hello world!</title>
  </head>
  <body>
    <div style="width: 50%">
      <div style="width: 50%">Hello world!</div>
    </div>
  </body>
</html>

我們可以看到,第一個div將節點的顯示尺寸設定為視口寬度的50%,第二個div將其尺寸設定為父節點的50%

而在迴流這個階段,我們就需要根據視口具體的寬度,將其轉為實際的畫素值

重繪(Painting)

最終,我們通過構造渲染樹和迴流階段,知道了那些元素是可見的,以及可見節點的樣式和具體的幾何影象資訊(也就是在頁面上的位置,大小)那麼我們就可以將渲染樹的每個節點都轉換為螢幕上的實際畫素,這個階段就叫做重繪節點

何時會發生迴流重繪?

既然前邊我們都知道了,迴流這一階段主要是計算節點的位置和幾何資訊,那麼當頁面佈局和幾何資訊發生變化的時候,就需要回流。舉幾個栗子:

        • 新增或刪除可見的DOM元素
        • 元素的位置發生變化
        • 元素的尺寸發生變化(包括外邊距、內邊框、邊框大小、高度和寬度等)
        • 內容發生變化,比如文字變化或圖片被另一個不同尺寸的圖片所替代。
        • 頁面一開始渲染的時候(這肯定避免不了)
        • 瀏覽器的視窗尺寸變化(因為迴流是根據視口的大小來計算元素的位置和大小的)

注意:迴流一定會觸發重繪,而重繪不一定會迴流

根據改變的範圍和程度,渲染樹中或大或小的部分需要重新計算,有些改變會觸發整個頁面的重排,比如,滾動條出現的時候或者修改了根節點

推薦騰訊 IVWEB 團隊的這篇文章:你真的瞭解迴流和重繪嗎

8,對BFC的理解

全程 block format contex 塊級格式上下文,就是一塊獨立渲染區域,不影響文件流

建立 BFC 的方式:

      • 絕對定位元素(position 為 absolute 或 fixed )。
      • 行內塊元素,即 display 為 inline-block 。
      • overflow 的值不為 visible 。

推薦文章:可能是最好的 BFC 解析了...

9,實現兩欄佈局(左側固定,右側自適應)

DOM結構:

<div class="outer">
  <div class="left">左側</div>
  <div class="right">右側</div>
</div>

方法一:

利用浮動,左邊元素寬度固定,右邊元素的margin-left固定,注意:右邊元素的width是auto,跟隨父級自動撐滿

.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  margin-left: 200px;
  height: 100%;
  background: lightseagreen;
}

方法二:

同樣利用浮動,將左邊元素寬度固定,然後給右邊元素加上overflow:hidden,這樣就觸發了 BFC ,BFC的區域不會與浮動元素髮生重疊,所以兩側就不會發生重疊

.outer {
  height: 100px;
}
.left {
  float: left;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  overflow: hidden;
  height: 100%;
  background: lightseagreen;
}

方法三:

利用 flex佈局,左邊元素固定寬度,右邊的元素設定  flex: 1

.outer {
  display: flex;
  height: 100px;
}
.left {
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  flex: 1;
  height: 100%;
  background: lightseagreen;
}

方法四:

利用定位,給父級元素相對定位,給左邊元素絕對定位,固定左邊元素的寬度,右邊元素margin-left 留出位置

.outer {
  position: relative;
  height: 100px;
}
.left {
  position: absolute;
  width: 200px;
  height: 100%;
  background: lightcoral;
}
.right {
  margin-left: 200px;
  height: 100%;
  background: lightseagreen;
}

方法五:

也是定位,給右邊元素絕對定位,給父級相對定位,然後固定左邊元素的寬度,給右邊元素設定 left 留出位置,剩餘的全為0

.outer { position: relative; height: 100px; }
.left { width: 200px; height: 100%; background: lightcoral; }
.right { position: absolute; left: 200px; top: 0; right: 0; bottom: 0; height: 100%; background: lightseagreen; }

10,實現聖盃佈局和雙飛翼佈局(經典的三欄佈局)

詢問聖盃佈局和雙飛翼佈局的目的:

  • 三欄佈局,中間的內容一定要優先渲染(內容最重要)
  • 兩邊固定,中間的隨著頁面自適應
  • 用於pc端頁面

技術總結:

  • 使用 float 佈局
  • 兩側使用 margin 負值,以便和中間內容橫向重疊
  • 防止中間內容被兩側覆蓋,聖盃佈局用 padding ,雙飛翼佈局用 margin

聖盃佈局:

<div id="container" class="clearfix">
  <p class="center">我是中間</p>
  <p class="left">我是左邊</p>
  <p class="right">我是右邊</p>
</div>

css樣式:

#container {
  padding-left: 200px;
  padding-right: 150px;
  overflow: auto;
}
#container p {
  float: left;
}
.center {
  width: 100%;
  background-color: lightcoral;
}
.left {
  width: 200px;
  position: relative;
  left: -200px;
  margin-left: -100%;
  background-color: lightcyan;
}
.right {
  width: 150px;
  margin-right: -150px;
  background-color: lightgreen;
}
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}

雙飛翼佈局:

<div id="main" class="float">
  <div id="main-wrap">main</div>
</div>
<div id="left" class="float">left</div>
<div id="right" class="float">right</div>

css樣式:

.float {
  float: left;
}
#main {
  width: 100%;
  height: 200px;
  background-color: lightpink;
}
#main-wrap {
  margin: 0 190px 0 190px;
}
#left {
  width: 190px;
  height: 200px;
  background-color: lightsalmon;
  margin-left: -100%;
}
#right {
  width: 190px;
  height: 200px;
  background-color: lightskyblue;
  margin-left: -190px;
}

11,水平垂直居中

方法一:flex 佈局

.box{
  display: flex;
  justify-content: center;
  align-items: center;
}

方法二:利用絕對定位,left:50% top:50% 然後再通過  margin-left  和 margin-top 設定負值實現

.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 200px;
  margin-left: -100px;
  margin-top: -100px;
}

方法三:和上邊的方法差不多,但用了css3新增的屬性 translate 來實現

.father {
  position: relative;
}
.son {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

方法四:利用絕對定位,子元素所有方向都為 0 ,將 margin  設定為 auto ,由於寬高固定,對應方向實現平分,注意:該方法必須盒子有寬高

.father {
  position: relative;
}
.son {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0px;
  margin: auto;
  height: 100px;
  width: 100px;
}

關於div居中的方法還有很多這裡推薦一篇:面試官:你能實現多少種水平垂直居中的佈局(定寬高和不定寬高)

12,flex佈局

Flex 是 Flexible Box 的縮寫,意為"彈性佈局",用來為盒狀模型提供最大的靈活性,任何一個容器都可以指定為 Flex 佈局

推薦閱讀:Flex 佈局教程 

13,line-height 如何繼承?

      • 父元素的 line-height 寫了具體數值,比如 30px,則子元素 line-height 繼承該值
      • 父元素的 line-height 寫了比例,比如 1.5 或 2,則子元素 line-height 也是繼承該比例
      • 父元素的 line-height 寫了百分比,比如 200%,則子元素 line-height 繼承的是父元素 font-size * 200% 計算出來的值