我们都晓得,外部引入 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 |
ID | 100 |
行内款式 | 1000 |
important | 1/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>
每一个款式的权重值,都在实例中,以解释的情势标明。
根据权重值可知,终究,这个按钮的款式一定是,蓝色背景,白色字,结果以下图:
存在!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结果以下图:
实例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结果以下图:
对照实例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结果以下图:
实例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结果以下图:
剖析实例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 English:http://taligarsiel.com/Projects/howbrowserswork1.htm