link和@import加载CSS文件的区别
CSS @import
@import
用于从其他样式表导入样式规则@import
必须在CSS文档的头部,但可以在@charset
规则后面@import
不是一个嵌套语句,不能在条件组的规则中使用@import
支持媒介查询
link和@import的区别
- 差别1:老祖宗的差别。link属于XHTML标签,而@import完全是CSS提供的一种方式。
link标签除了可以加载CSS外,还可以做很多其它的事情,比如定义RSS,定义rel连接属性等,@import就只能加载CSS了。
- 差别2:加载顺序的差别。
当在外联css文件A中使用@import引用另一个css文件B时,只有等css文件 A下载完解析时,浏览器才知道还有css文件B需要下载,此时css文件A和css文件B是串行加载的。 如果css文件A和css文件B都是通过link加载,则是并行的。
- 差别3:兼容性的差别。
由于@import是CSS2.1提出的所以老的浏览器不支持,@import只有在IE5以上的才能识别,而link标签无此问题。
- 差别4:使用dom控制样式时的差别。
我们可以通过js创建一个link标签,然后加载一个css文件。从而改变某一个dom的样式。而js是无法控制@import的。
let link = document.createElement('link')
link.href = './link.css'
link.rel = 'stylesheet'
document.body.append(link)
不建议使用@import
之所以要把这个删除掉:因为现在大多数项目都会经过webpack、vite这些工具进行打包。打包后@import可能也就被替换掉了,也就不存在下面那些问题了。
webpack通过css-loader对@import的默认处理
webpack + css-loader 测试:
- 安装css-loader、style-loader
- 配置webpack.config.js文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
optimization: {
runtimeChunk: 'single',
},
};
- 在根目录下创建src文件夹
- src文件夹下新建index.js文件,在该文件中引用css文件
import css from './link.css';
- 在src文件夹下新建link.css文件
@import url(@import.css);
.box {
width: 400px;
height: 400px;
background-color: aqua;
}
- 在src文件夹下新建@import.css文件
.box {
width: 100px;
height: 100px;
background-color: green;
}
- 执行webpack,打包后的结果文件内容如下
webpack 将@import 转化为自定义的__webpack_require__方法导入
"use strict";
(self["webpackChunkcss_loader"] = self["webpackChunkcss_loader"] || []).push([[792],{
/***/ 943:
/***/ ((module, __webpack_exports__, __webpack_require__) => {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(236);
/* harmony import */ var WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(517);
/* harmony import */ var WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(WEBPACK_IMPORTED_MODULE_1__);
// Imports
var ___CSS_LOADER_EXPORT___ = WEBPACK_IMPORTED_MODULE_1___default()((WEBPACK_IMPORTED_MODULE_0___default()));
// Module
___CSS_LOADER_EXPORT___.push([module.id, `.box {
width: 100px;
height: 100px;
background-color: green;
}`, ""]);
// Exports
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
/***/ }),
/***/ 638:
/***/ ((module, __webpack_exports__, __webpack_require__) => {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(236);
/* harmony import */ var WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(517);
/* harmony import */ var WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(943);
//link.css文件通过@import引用@import.css文件转化为了webpack自定义的导入方法__webpack_require__
// Imports
var ___CSS_LOADER_EXPORT___ = _node_modules_pnpm_css_loader_7_1_1_webpack_5_91_0_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_pnpm_css_loader_7_1_1_webpack_5_91_0_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
___CSS_LOADER_EXPORT___.i(_node_modules_pnpm_css_loader_7_1_1_webpack_5_91_0_node_modules_css_loader_dist_cjs_js_import_css__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A);
// Module
___CSS_LOADER_EXPORT___.push([module.id, `.box {
width: 400px;
height: 400px;
background-color: aqua;
}`, ""]);
// Exports
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
/***/ }),
webpack还可以通过插件mini-css-extract-plugin
将css提取到单独文件中
webpack + css-loader + mini-css-extract-plugin测试
- webpack配置文件如下:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin(),
new MiniCssExtractPlugin()
],
optimization: {
runtimeChunk: 'single',
minimize: false
},
};
- webpack打包后结果文件内容如下:
在vite中会默认通过posscss-import对@import进行处理:
postcss-import测试:
待转换的css文件:
@import url(@import.css);
.box {
width: 400px;
height: 400px;
background-color: aqua;
}
postcss-import官方例子
// dependencies
const fs = require("fs")
const postcss = require("postcss")
const atImport = require("postcss-import")
// css to be processed
const css = fs.readFileSync("./link.css", "utf8")
// process css
postcss()
.use(atImport())
.process(css, {
// `from` option is needed here
from: "link.css"
})
.then((result) => {
const output = result.css
console.log(output)
})
执行后的输出结果:
Vite+Vue3项目的一个例子:
- 在某一个Vue3+Vite项目的子组件中编写如下css代码:
HelloWorld.vue
<style scoped>
@import url(./HelloWorld.css);
.box {
line-height: 100px;
color: #fff;
}
</style>
HelloWorld.css
.box {
width: auto;
height: 200px;
background-color: red;
}
- 默认情况下vite的处理结果为:
- 原因一:使用@import引入的CSS会影响浏览器的并行下载
使用@import引用的CSS文件只有在引入它的那个CSS文件被下载、解析之后,浏览器才会知道还有另外一个CSS需要下载,这时才会去下载,然后下载后开始解析、构建render tree等一系列操作。这就导致了浏览器无法并行下载所需的样式文件。
案例A:在css文件中@import另一个css文件, 串行加载
link.css
@import url(./@import.css);
.box {
width: 200px;
height: 300px;
background-color: red;
}
@import.css
.box {
width: 100px;
height: 100px;
background-color: green;
}
案例B:2个css文件都使用link加载,并行加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="./@import.css" rel="stylesheet" />
<link href="./link.css" rel="stylesheet" />
</head>
<body>
<div class="box"></div>
</body>
</html>
- 原因2: @import 是 CSS2.1 才出现的概念,所以如果浏览器版本较低,无法正确导入外部样式文件。
转载自:https://juejin.cn/post/7356114363881455655