link和@import的区分浅析

我们都晓得,外部引入 CSS 有2种体式格局,link标签和@import
它们有何本质区分,有何运用发起,在考核外部引入 CSS 这部分内容时,经常被提起。

如今,许多学者本着知其然不欲知其所以然的进修态度,囫囵吞枣,只求结论。
所以,本文遵照 css hack 的渐进辨认准绳,
结论 → 区分 → 争议 → 细节 → 祖坟 → 感受,逐步加深理论层级,
力图每一个 level 的读者,都能 get 到自身想要的内容,没必要继续浏览下去。

结论

就结论而言,强烈发起运用link标签,慎用@import体式格局。
如许能够防止斟酌@import的语法划定规矩和注意事项,防止发生资本文件下载递次杂沓和http要求过量的懊恼。

区分

1.从属关系区分
@import是 CSS 供应的语法划定规矩,只要导入款式表的作用;link是HTML供应的标签,不仅能够加载 CSS 文件,还能够定义 RSS、rel 衔接属性等。

2.加载递次区分
加载页面时,link标签引入的 CSS 被同时加载;@import引入的 CSS 将在页面加载终了后被加载。

3.兼容性区分
@import是 CSS2.1 才有的语法,故只可在 IE5+ 才辨认;link标签作为 HTML 元素,不存在兼容性题目。

4.DOM可控性区分
能够经由历程 JS 操纵 DOM ,插进去link标签来转变款式;因为 DOM 要领是基于文档的,没法运用@import的体式格局插进去款式。

5.权重区分(该项有争议,下文将详解)
link引入的款式权重大于@import引入的款式。

争议

不知从什么时刻最先,当你在网上搜刮link@import的区分时,一模一样的答案里就偷偷的多了一句“link引入的款式权重大于@import引入的款式”。
然则并没有一份答案,附带着对这句话的任何诠释或实例。

这句话终究是什么意思,该怎样邃晓呢?

发扬探究精力,我们无妨继续查阅材料。厥后发明,照样有不少文章和帖子,对这句话示意质疑,进而自身写了 demo 去考据,考据的结果,确切没法与这句话相吻合。
而且,笔者也并未发明能清晰、准确、有理有据的诠释这个结论终究对,照样不对的文章。

那末这个结论,最初是从哪里来的,能够已无从考据了。

换个头脑体式格局,不去狡辩它的对错了,探究未果,我们就从这个结论的中心关键词“权重”动身,去研讨它。

说到“权重”,有必要再诠释一下:CSS 中的权重,指的是选择器的优先级。

CSS 选择器的权重高,即选择器的优先级高。
CSS 的优先级特征表现为,对统一 HTML 元素设置款式时,差别选择器的优先级差别,优先级低的款式将被高优先级的款式层叠掉。

CSS 权重优先级递次简朴示意为:
!important > 行内款式 > ID > 类、伪类、属性 > 标署名 > 继续 > 通配符

为了便于邃晓权重的盘算体式格局,我们按以下体式格局举行数值假定剖析:

选择器权重
通配符0
标签1
类/伪类/属性10
ID100
行内款式1000
important1/0(无穷大)

再举实例:

<!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的区分浅析》

存在!important时,不作他想,一定是权重最大的款式。

既然我们相识了,CSS 中的权重是怎样回事,那回到主题,“link引入的款式权重大于@import引入的款式”,
岂非 CSS 的引入体式格局也有权重吗?实在我们没必要纠结它是不是有权重之说,我们只需理论结合实际的去剖析,种种情况下,结果怎样即可。
现有以下3个css文件:

/* 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;
}

实例1:

<!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>

实例1结果以下图:
《link和@import的区分浅析》

实例2:

<!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>

实例2结果以下图:
《link和@import的区分浅析》

对照实例1和实例2这两个恰好相反的结果可知,link@import并没有发生相似权重的结果,只是纯真的表现了CSS的层叠性,写在背面的款式,掩盖前面的款式。

实例3:

<!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>

实例3结果以下图:
《link和@import的区分浅析》

实例4:

<!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>

实例4结果以下图:
《link和@import的区分浅析》

剖析实例3和实例4的结果可知:

关于实例3,我们看到赤色边框,证实内联款式中运用@import引入的green.css已见效,但其背景款式被内联款式中的粉色背景层叠掉,这个征象表明,@import不只是如我们看到的那样,处于内联款式顶部,其被引入的款式,在结构上,也确切是被置于内联款式之前,所以内联款式才够层叠掉它。

同理,实例4中,在link标签引入的blue.css文件内,顶部一样存在@import引入的green.css,赤色边框依旧能够证实,green.css已见效,但其背景款式被blue.css自身的蓝色背景层叠掉,@import引入的款式在blue.css中也是被置于它自身款式之前的。

到此为止,我展开了斗胆勇敢的猜想,“link引入的款式权重大于@import引入的款式”,这个结论的给出者,是想通知人人:

link标签引入的 CSS 文件中,运用@import时需注意,假如已存在雷同款式,@import引入的这个款式将被该 CSS 文件自身的款式层叠掉,表现出link标签引入的款式权重大于@import引入的款式如许的直观结果。

关于我设想的结论,好像挺能说通的,毕竟这是实践出的结果。

那些考据过此结论的前人,他们都是在一个 HTML 页面中,一前一后离别运用link和内联款式的@import去比较的,我在实例1和实例2中也是云云做的,并不能反推出“link引入的款式权重大于@import引入的款式”这个结论,所以,我蚍蜉撼树的以为,这个结论实在最初只是丢了个已知前提罢了。

那末我们一同把这个结论从新梳理一下:在link标签引入的 CSS 文件中运用@import时,雷同款式将被该 CSS 文件自身的款式层叠。

Ps.起首谢谢种种看官的浏览。笔者属于进修阶段,学问尚浅,虽然本文结论已得到笔者编码考据,但不消除笔者大脑短路、说话有误的能够,有缘浏览到此处的都是真爱,愿望诸位大拿、大牛、大仙、大圣、大神们不吝赐教,实时斧正,防止引诱萌新误入歧途,再次向你们表达笔者的谢意!

细节

既然已说了这么多,就趁便提一下关于@import运用时的别的细节。

在《CSS威望指南》中写道:

@import一定要写在除@charset外的其他任何 CSS 划定规矩之前,假如置于别的位置将会被浏览器疏忽,而且,在@import以后假如存在别的款式,则@import以后的分号是必需誊写,不可省略的。

到此为止,好像事变都弄清晰了,然则倏忽又有个疑点显现出来:

在议论区分的时刻,不是说加载页面时,link标签引入的 CSS 先于@import引入的 CSS 加载吗,那link标签引入的款式又怎会把@import引入的款式层叠掉呢?

要回答这个题目,起首我们要一同邃晓一些有关浏览器的观点:

浏览器实行历程能够简朴分为加载、剖析、衬着,这三个步骤。

加载:根据要求的URL举行域名剖析,向服务器发送要求,吸收响应文件(如 HTML、JS、CSS、图片等)。

剖析:对加载到的资本(HTML、JS、CSS等)举行语法剖析,构建响应的内部数据结构(比方HTML的DOM树,JS对象的属性表,CSS的款式划定规矩等)。

衬着:构建衬着树,对各个元素举行位置盘算、款式盘算等,然后根据衬着树完成页面规划及绘制的历程(能够邃晓为“画”页面元素)。

这几个历程不是完整伶仃的,会有交织,比方HTML加载后就会举行剖析,然后拉取HTML中指定的CSS、JS等。`

如今,我们应当已相识了加载和衬着的观点,邃晓它们是两个差别的历程,那末对上文中抛出的疑问继续诘问:

link先于@import加载,是不是是也先于@import衬着呢?

实际上,衬着的行动平常都邑实行屡次,末了一次衬着,一定是根据之前加载过的一切款式整合后的衬着树举行绘制页面的,已被衬着过的页面元素,也会被从新衬着。

那末我们就能够把@import这类导入 CSS 文件的体式格局邃晓成一种替代,CSS 剖析引擎在对一个 CSS 文件举行剖析时,如在文件顶部碰到@import,将被替代为该@import导入的 CSS 文件中的悉数款式。

峰回路转,山穷水尽,终究弄邃晓为什么@import引入的款式,会被层叠掉了。其虽然后被加载,却会在加载终了后置于款式表顶部,终究衬着时天然会被下面的同名款式层叠。

至此为止,“link引入的款式权重大于@import引入的款式”这个结论,我终究为它圆了场。希望此结论的作者,本意真如我的猜想,不然如果我多心而跑偏了的话,不敢设想这背地终究隐藏着多大的隐秘。

祖坟

有些仔细而专业的读者能够已发明了,我用自身的思绪和说话,大略的诠释了有关 CSS 加载和衬着的学问,有些涉世未深的前端兴趣者能够会一头雾水,没法作为体系进修的根据。这不打紧,出来混,祖坟老是要刨的,想要透辟的进修相关内容,进一步相识底层道理的学者,我早已为你备下了丰盛的见面礼~

有关link@import在机能剖析方面的比较,外洋的高手早在多年前就曾执过笔:

兴趣母语的请戳我https://www.stevesouders.com/blog/2009/04/09/dont-use-import/
浏览英语的请戳我https://www.qianduan.net/high-performance-web-site-do-not-use-import/

有关浏览器内部事情道理的神作,也是几年前出自歪果仁大牛:

1 为普通话https://kb.cnblogs.com/page/129756/
2 for Englishhttp://taligarsiel.com/Projects/howbrowserswork1.htm

    原文作者:马蹄丙
    原文地址: https://segmentfault.com/a/1190000015950516
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞