关于 @import 和 link 引入样式的区别网上有很多种说法. 大致有如下几种, 不过这其中会有我存疑的地方, 我们可以一起来探讨一下.
区别
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 引入的样式.(???)
我们在网上搜索关于这两者的区别的时候通常会看见有第 5 条这么一个说法. 难道第 5 条真的是这样吗? 有待商榷.
所以这里我们就通过几个 demo 来验证一下第五条
再验证之前我们先来说说 CSS 权重的相关概念:
CSS 的权重指的是选择器的优先级, CSS 选择器的权重高, 即选择器的优先级高.
CSS 的优先级表现在, 对同一个 HTML 元素设置元素的时候, 不同选择器的优先级不同, 优先级低的样式将会被优先极高的样式所覆盖.
CSS 的权重优先级表现为:
!important> 行内样式> ID> 类, 伪类, 属性> 标签名> 继承> 通配符
为了便于理解权重的计算方式, 我们按以下方式进行数值假设分析:
demo:
web 前端开发学习 Q-q-u-n: 731771211, 分享学习的方法和需要注意的小细节, 不停更新最新的教程和学习方法(详细的前端项目实战教学视频)
- <!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>
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>
对比 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>
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>
分析实例 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 引入的样式, 会被层叠掉了. 其虽然后被加载, 却会在加载完毕后置于样式表顶部, 最终渲染时自然会被下面的同名样式层叠.
自己是一个 6 年的前端工程师, 希望本文对你有帮助!
这里推荐一下我的前端学习交流扣 qun:731771211 , 里面都是学习前端的, 如果你想制作酷炫的网页, 想学习编程. 自己整理了一份 2019 最全面前端学习资料, 从最基础的 HTML+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴, 每天分享技术
点击: 加入
来源: http://www.jianshu.com/p/7377bbbe94b1