你真的理解@import和link引入樣式的區別嗎

最近在作知識體系的覆盤,在覆盤的時候儘量的查漏補缺。關於@import和link引入樣式的區別網上有不少種說法。大體有以下幾種,不過這其中會有我存疑的地方,咱們能夠一塊兒來探討一下。css

區別

1.從屬關係區別

@import是 CSS 提供的語法規則,只有導入樣式表的做用;link是HTML提供的標籤,不只能夠加載 CSS 文件,還能夠定義 RSS、rel 鏈接屬性等。html

2.加載順序區別

加載頁面時,link標籤引入的 CSS 被同時加載;@import引入的 CSS 將在頁面加載完畢後被加載。瀏覽器

3.兼容性區別

@import是 CSS2.1 纔有的語法,故只可在 IE5+ 才能識別;link標籤做爲 HTML 元素,不存在兼容性問題。bash

4.DOM可控性區別

能夠經過 JS 操做 DOM ,插入link標籤來改變樣式;因爲DOM方法是基於文檔的,沒法使用@import的方式插入樣式。服務器

5.權重區別

link引入的樣式權重大於@import引入的樣式。(???)數據結構

咱們在網上搜索關於這二者的區別的時候一般會看見有第5條這麼一個說法。難道第5條真的是這樣嗎?有待商榷。佈局

因此這裏咱們就經過幾個demo來驗證一下第五條字體

再驗證以前咱們先來講說css權重的相關概念:ui

css的權重指的是選擇器的優先級,CSS 選擇器的權重高,即選擇器的優先級高。url

css的優先級表如今,對同一個html元素設置元素的時候,不一樣選擇器的優先級不一樣,優先級低的樣式將會被優先極高的樣式所覆蓋。

css的權重優先級表現爲:

!important > 行內樣式 > ID > 類、僞類、屬性 > 標籤名 > 繼承 > 通配符

爲了便於理解權重的計算方式,咱們按如下方式進行數值假設分析:

選擇器 權重
通配符 0
標籤 1
類/僞類/屬性 10
ID 100
行內樣式 1000
important 無窮大

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        #myid { /* id選擇器權重爲100 */
            background-color: pink;
        }
        #divid .myspan input { /* 權重爲 100 + 10 + 1 = 111 */
            background-color: yellow;
        }
        input[type="button"] { /* 權重爲 10 */
            color: white !important; /* !important權重爲無窮大 */
        }
        input.myclass { /* 此爲標籤指定式選擇器,權重爲 1 + 10 = 11 */
            color: black;
        }
    </style>
</head>
<body>
    <div id="divid">
        <span class="myspan">
            <input type="button" id="myid" class="myclass" name="myname"
                value="點我" style=" color: green;">
                <!-- style樣式的權重爲1000 -->
        </span>
    </div>
</body>
</html>複製代碼

根據上述計算得知:這個按鈕應該是黃色背景,白色字體。

這裏又回到咱們的主題:link引入的樣式權重真的大於@import嗎?

難道引入css的方式也會有權重嗎?

上demo:

/* green.css */
div {
    background-color: green;
    border: 3px solid red;
}

/* yellow.css */
div {
    background-color: yellow;
    border: 3px solid black;
}

/* blue.css */
@import url("green.css");
div{
    background-color: blue;
}複製代碼

eg1)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- 實例1. link標籤引入yellow.css,內聯樣式引入green.css -->
    <link rel="stylesheet" href="yellow.css">
    <style type="text/css">
        @import url("green.css");
    </style>
</head>
<body>
    <div style="width: 50px; height: 50px;"></div>
    <!-- 盒子爲,綠色背景,紅色邊框,即green.css生效 -->
</body>
</html>複製代碼

效果:image

eg2)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- 實例2. 內聯樣式引入green.css,link標籤引入yellow.css -->
    <style type="text/css">
        @import url("green.css");
    </style>
    <link rel="stylesheet" href="yellow.css">
</head>
<body>
    <div style="width: 50px; height: 50px;"></div>
    <!-- 盒子爲黃色背景,黑色邊框,即yellow.css生效 -->
</body>
</html>複製代碼

效果:image

對比1和2兩個例子,咱們發現link和@import這兩種引入css的方式並無權重方面概念,只是單純的展現出css的層疊行罷了。即寫在後邊都樣式會覆蓋前面的樣式。

eg3)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- 實例3. 內聯樣式引入green.css,內聯樣式中設置粉色背景 -->
    <style type="text/css">
        @import url("green.css");
        div {
            background-color: pink;
        }
    </style>
</head>
<body>
    <div style="width: 50px; height: 50px;"></div>
    <!-- 盒子爲粉色背景,紅色邊框,即green.css已生效,但背景色被內聯樣式層疊爲粉色 -->
</body>
</html>複製代碼

效果:image

eg4)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- 實例4. link標籤引入blue.css,blue.css中引入green.css -->
    <link rel="stylesheet" href="blue.css">
</head>
<body>
    <div style="width: 50px; height: 50px;"></div>
    <!-- 盒子爲藍色背景,紅色邊框,即green.css已生效,但背景色被blue.css層疊爲藍色 -->
</body>
</html>複製代碼

效果:image

分析實例3和實例4的結果可知:

對於實例3,咱們看到紅色邊框,證實內聯樣式中使用@import引入的green.css已經生效,但其背景樣式被內聯樣式中的粉色背景層疊掉,這個現象代表,@import不僅是如咱們看到的那樣,處於內聯樣式頂部,其被引入的樣式,在結構上,也確實是被置於內聯樣式以前,因此內聯樣式纔可以層疊掉它。

同理,實例4中,在link標籤引入的blue.css文件內,頂部一樣存在@import引入的green.css,紅色邊框依然能夠證實,green.css已經生效,但其背景樣式被blue.css自己的藍色背景層疊掉,@import引入的樣式在blue.css中也是被置於它自己樣式以前的。

因此由上述實例證實link引入的樣式權重大於@import引入的樣式這麼說是不太合理的。

疑點?

咱們上邊也說了關於link@import的區別,在加載頁面的時候,不是說在link引入的css樣式的時候會先於@import加載嗎?那爲啥link引入的樣式又會覆蓋掉@import引入的樣式啊?

首先咱們來回顧一下關於瀏覽器執行過程的一些概念:

加載: 根據請求的url進行域名解析,而後向服務器發送請求,接收響應文件(如HTML、CSS、JS、圖片等)。

解析: 對加載到的資源(HTML、CSS、JS等)進行語法解析,構建響應的內部數據結構(如HTML的DOM樹,JS對象的屬性表,css樣式規則等)。

渲染: 構建渲染樹,對各個元素進行位置計算、樣式計算等,而後根據渲染書完成頁面的佈局及繪製的過程(產生頁面的元素)。

因此根據咱們上述的瀏覽器執行過程的理解之後,咱們我繼續提出疑問:

link先於@import加載,是否是也先於@import渲染呢?

實際上,瀏覽器渲染的動做通常會執行屢次的。最後一次渲染,必定是基於以前加載過的全部樣式整合後渲染樹進行繪製頁面的,已經被渲染過的頁面元素,也會被從新渲染。

那麼咱們就能夠把@import這種導入 CSS 文件的方式理解成一種替換,CSS 解析引擎在對一個 CSS 文件進行解析時,如在文件頂部遇到@import,將被替換爲該@import導入的 CSS 文件中的所有樣式。

終於弄明白爲什麼@import引入的樣式,會被層疊掉了。其雖而後被加載,卻會在加載完畢後置於樣式表頂部,最終渲染時天然會被下面的同名樣式層疊。

相關文章
相關標籤/搜索