CSS
Parcel 包含对 CSS 的开箱即用支持。要添加 CSS 文件,请在 HTML 文件中使用 <link>
标签引用它
<link rel="stylesheet" href="index.css" />
或从 JavaScript 文件导入它
import './index.css';
依赖项
#CSS 资产可以包含通过 @import
语法引用的依赖项,以及通过 url()
函数引用的图像、字体等。
@import
#@import
at-规则可用于将另一个 CSS 文件内联到与包含文件相同的 CSS 包中。这意味着在运行时,不需要单独的网络请求来加载依赖项。
@import 'other.css';
引用的文件应相对于包含的 CSS 文件 相对。您也可以使用 绝对 和 波浪号 指定符。要从 npm 导入 CSS 文件,请使用 npm:
方案。
@import 'npm:bootstrap/bootstrap.css';
当启用 @parcel/resolver-glob
插件时,您也可以使用 glob 同时导入多个 CSS 文件。有关更多详细信息,请参阅 Glob 指定符。
@import "./components/*.css";
url()
#url()
函数可用于引用文件,例如背景图像或字体。引用的文件将由 Parcel 处理,并且 URL 引用将被重写以指向输出文件名。
body {
background: url(images/background.png);
}
引用的文件应相对于包含的 CSS 文件 相对。您也可以使用 绝对 和 波浪号 指定符。data-url:
方案也可用于将文件内联为数据 URL。有关更多详细信息,请参阅 包内联。
.logo {
background: url('data-url:./logo.png');
}
CSS 模块
#默认情况下,从 JavaScript 导入的 CSS 是全局的。如果两个 CSS 文件定义了相同的类名、id、自定义属性、@keyframes
等,它们可能会发生冲突并相互覆盖。为了解决这个问题,Parcel 支持 CSS 模块。
CSS 模块将每个文件中定义的类视为唯一的。每个类名或标识符都会被重命名以包含一个唯一的哈希值,并且一个映射会被导出到 JavaScript 以便引用它们。
要使用 CSS 模块,请创建一个扩展名为 .module.css
的文件,并使用 命名空间导入 从 JavaScript 文件中导入它。然后,您可以将 CSS 文件中定义的每个类作为模块的导出进行访问。
import * as classes from './styles.module.css';
document.body.className = classes.body;
.body {
background: skyblue;
}
.body
类将被重命名为一个唯一的值,以避免与其他 CSS 文件中的选择器冲突。
CSS 模块也适用于其他编译为 CSS 的语言,例如 SASS、Less 或 Stylus。使用相应的扩展名命名您的文件,例如 .module.scss
、.module.less
或 .module.styl
。
摇树优化
#使用 CSS 模块还有另一个好处,那就是使代码中对特定类名的依赖关系变得明确。这使得未使用的 CSS 类可以自动删除。
如您在上面的示例中看到的,只使用了 .button
类,因此未使用的 .cta
类已从编译后的 CSS 文件中删除。
这也适用于其他未使用的 CSS 规则,例如 @keyframes
和 @counter-style
,以及 CSS 自定义属性(当启用 dashedIdents
选项时)。
本地 CSS 变量
#默认情况下,类名、id 选择器以及 @keyframes
、@counter-style
以及 CSS 网格线和区域的名称都限定在它们定义的模块中。可以使用项目根目录 package.json
中的 dashedIdents
配置选项来启用对 CSS 变量和其他 <dashed-ident>
名称的限定。
{
"@parcel/transformer-css": {
"cssModules": {
"dashedIdents": true
}
}
}
启用后,CSS 变量将被重命名,以避免与其他文件中定义的变量名冲突。引用变量使用标准的 var()
语法,Parcel 将更新它以匹配本地限定的变量名。
您也可以使用 from
关键字引用其他文件中定义的变量
.button {
background: var(--accent-color from "./vars.module.css");
}
:root {
--accent-color: hotpink;
}
可以使用 from global
语法引用全局变量,但是,它们目前必须在非 CSS 模块文件中定义。
@import "vars.css";
.button {
color: var(--color from global);
}
:root {
--color: purple;
}
相同的语法也适用于使用 <dashed-ident>
语法的其他 CSS 值。例如,@font-palette-values 规则和 font-palette 属性使用 <dashed-ident>
语法来定义和引用自定义字体颜色调色板,并且将以与 CSS 变量相同的方式进行限定和引用。
自定义命名模式
#默认情况下,Parcel 会将文件名的哈希值作为前缀添加到 CSS 文件中的每个类名和标识符。您可以使用项目根目录 package.json
中的 "pattern"
选项来配置此命名模式。它接受一个包含占位符的字符串,这些占位符将由 Parcel 填充,允许您添加自定义前缀或调整限定类的命名约定。
{
"@parcel/transformer-css": {
"cssModules": {
"pattern": "my-company-[name]-[hash]-[local]"
}
}
}
目前支持以下占位符
[name]
- 文件的基本名称,不包含扩展名。[hash]
- 完整文件路径的哈希值。[local]
- 原始类名或标识符。
注意:由于浏览器会自动添加后缀,导致网格模板区域的线名以 -start
和 -end
结尾,因此 CSS 网格线名可能会出现歧义。使用 CSS 网格时,您的 "pattern"
配置必须以 [local]
占位符结尾,以便这些引用能够正常工作。
.grid {
grid-template-areas: "nav main";
}
.nav {
grid-column-start: nav-start;
}
{
"@parcel/transformer-css": {
"cssModules": {
// ❌ [local] must be at the end so that
// auto-generated grid line names work
"pattern": "[local]-[hash]"
// ✅ do this instead
"pattern": "[hash]-[local]"
}
}
}
全局启用 CSS 模块
#默认情况下,CSS 模块仅对名称以 .module.css
结尾的文件启用。默认情况下,所有其他 CSS 文件都被视为全局 CSS。但是,可以通过在项目根目录 package.json
中配置 @parcel/transformer-css
来覆盖此行为,以便为所有源文件(即不在 node_modules
中的文件)启用 CSS 模块。
{
"@parcel/transformer-css": {
"cssModules": true
}
}
使用包含其他选项的配置对象时,请使用 "global"
选项。
{
"@parcel/transformer-css": {
"cssModules": {
"global": true,
// ...
}
}
}
注意:在 Parcel 的早期版本中,postcss-modules
用于实现 CSS 模块支持。全局启用 CSS 模块是在项目的 PostCSS 配置文件中完成的。如果您按上述方式启用 CSS 模块,则可以从 PostCSS 配置文件中删除此插件。
如果这是您使用的唯一 PostCSS 插件,则可以完全删除 PostCSS 配置文件。这可以显著提高构建性能。如果您没有使用任何 postcss-modules
配置选项,您可能会看到有关此问题的警告。
转译
#Parcel 包含对转译现代 CSS 语法以支持旧版浏览器的开箱即用支持,包括供应商前缀和语法降低。此外,还支持 PostCSS 以启用自定义 CSS 转换。
浏览器目标
#默认情况下,Parcel 不会对旧版浏览器执行任何 CSS 语法转译。这意味着如果您使用现代语法或不带供应商前缀编写代码,Parcel 将输出的就是这些代码。您可以使用 package.json
中的 browserslist
字段声明应用程序支持的浏览器。声明此字段后,Parcel 将相应地转译您的代码,以确保与支持的浏览器兼容。
{
"browserslist": "> 0.5%, last 2 versions, not dead"
}
有关如何配置此功能的更多详细信息,请参阅 目标 文档。
供应商前缀
#根据您配置的浏览器目标,Parcel 会自动为许多 CSS 功能添加供应商前缀回退。例如,使用 image-set()
函数时,Parcel 还会输出回退 -webkit-image-set()
值,因为 Chrome 尚未支持未加前缀的值。
.logo {
background: image-set(url(logo.png) 2x, url(logo.png) 1x);
}
编译为
.logo {
background: -webkit-image-set(url(logo.png) 2x, url(logo.png) 1x);
background: image-set("logo.png" 2x, "logo.png");
}
此外,如果您的 CSS 源代码(或更可能是库)包含不必要的供应商前缀,Parcel CSS 会自动删除它们,以减小包大小。例如,在为现代浏览器编译时,transition
属性的前缀版本将被删除,因为所有浏览器都支持未加前缀的版本。
.button {
-webkit-transition: background 200ms;
-moz-transition: background 200ms;
transition: background 200ms;
}
变为
.button {
transition: background .2s;
}
语法降低
#Parcel 会自动将许多现代 CSS 语法功能编译为更兼容的输出,这些输出在您的目标浏览器中受支持。
支持以下功能
- 颜色级别 5
color-mix()
函数
- 颜色级别 4
- 逻辑属性,例如
margin-inline-start
- 媒体查询范围语法,例如
@media (width <= 100px)
或@media (100px < width < 500px)
- 对齐简写,例如
place-items
和place-content
clamp()
函数- 双位置渐变停止(例如
red 40% 80%
) - 双值
overflow
简写 - 多值
display
属性(例如inline flex
)
草案语法
#Parcel 还可以配置为编译一些尚未在任何浏览器中原生提供的草案规范。由于这些是草案,语法仍然可能发生变化,因此必须在项目中手动启用它们。
嵌套
#The CSS 嵌套 草案规范允许样式规则进行嵌套,子规则的选择器以某种方式扩展父选择器。这在 SASS 等 CSS 预处理器中非常普遍,但有了这个规范,它最终将在浏览器中得到原生支持。Parcel 将此语法编译为今天所有浏览器都支持的非嵌套样式规则。
由于嵌套是草案,因此默认情况下不会启用它。要使用它,请通过在项目根目录的 package.json
文件中配置 @parcel/transformer-css
来启用它。
{
"@parcel/transformer-css": {
"drafts": {
"nesting": true
}
}
}
启用后,项目中的任何 CSS 文件都可以直接使用嵌套样式规则或 @nest
at 规则。
直接嵌套的样式规则 必须以 &
嵌套选择器为前缀。这指示父选择器将在哪里被替换。例如
.foo {
color: blue;
& > .bar { color: red; }
}
等效于
.foo { color: blue; }
.foo > .bar { color: red; }
The @nest 规则 允许在父选择器被替换为开始位置以外的其他位置时进行嵌套。
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
等效于
.foo { color: red; }
.parent .foo { color: blue; }
条件规则,例如 @media
,也可以嵌套在样式规则中,而无需重复选择器。例如
.foo {
display: grid;
@media (orientation: landscape) {
grid-auto-flow: column;
}
}
等效于
.foo { display: grid; }
@media (orientation: landscape) {
.foo {
grid-auto-flow: column;
}
}
自定义媒体查询
#对 自定义媒体查询 的支持包含在媒体查询级别 5 草案规范中。这允许您定义在 CSS 文件中的多个位置重复使用的媒体查询。Parcel CSS 将在启用此功能时提前执行此替换。
例如
@custom-media --modern (color), (hover);
@media (--modern) and (width > 1024px) {
.a { color: green; }
}
等效于
@media ((color) or (hover)) and (width > 1024px) {
.a { color: green; }
}
由于自定义媒体查询是草案,因此默认情况下不会启用它们。要使用它们,请通过在项目根目录的 package.json
文件中配置 @parcel/transformer-css
来启用 customMedia
功能。
{
"@parcel/transformer-css": {
"drafts": {
"customMedia": true
}
}
}
伪类替换
#Parcel 支持将 :focus-visible
等 CSS 伪类替换为可以使用 JavaScript 应用的普通 CSS 类。这使得为旧版浏览器填充这些伪类成为可能。
伪类映射可以在项目根目录的 package.json
文件中配置
{
"@parcel/transformer-css": {
"pseudoClasses": {
"focusVisible": "focus-visible"
}
}
}
上面的配置将导致所有选择器中的 :focus-visible
伪类被替换为 .focus-visible
类。这使您能够使用 JavaScript polyfill,它将根据需要应用 .focus-visible
类。
以下伪类可以按上述方式配置
hover
– 对应于:hover
伪类active
– 对应于:active
伪类focus
– 对应于:focus
伪类focusVisible
– 对应于:focus-visible
伪类focusWithin
– 对应于:focus-within
伪类
PostCSS
#PostCSS 是一个使用插件转换 CSS 的工具。虽然 Parcel 支持许多常见 PostCSS 插件(例如 autoprefixer 和 postcss-preset-env)的等效功能,如上所述,PostCSS 对于更自定义的 CSS 转换(例如非标准语法添加)很有用。它也被流行的 CSS 框架(例如 Tailwind)使用。
您可以通过使用以下名称之一创建配置文件来在 Parcel 中使用 PostCSS:.postcssrc
、.postcssrc.json
、.postcssrc.js
、.postcssrc.mjs
、.postcssrc.cjs
、postcss.config.js
、postcss.config.mjs
或 postcss.config.cjs
。
首先,将您希望在应用程序中使用的 postcss 插件安装到您的应用程序中
yarn add tailwindcss --dev
然后,创建一个 .postcssrc
。插件在 plugins
对象中作为键指定,选项使用对象值定义。如果插件没有选项,只需将其设置为 true
即可。
如果您的插件需要额外的配置,请也创建这些文件。例如,使用 Tailwind,您需要一个 tailwind.config.js
。
{
"plugins": {
"tailwindcss": true
}
}
module.exports = {
content: ["./src/*.{html,js}"],
theme: {
extend: {},
},
variants: {},
plugins: [],
};
默认插件
#当在您的 package.json
中指定 browserslist
时,Parcel 会自动包含 autoprefixer
和 postcss-preset-env
的等效项。这些 在 Rust 中实现,并且比 PostCSS 快得多。如果这些是您项目中唯一需要的转换,那么您可能根本不需要 PostCSS。
如果您有一个现有项目,其中 PostCSS 配置仅包含上述插件,您可能可以完全删除它。如果您使用的是其他插件,您可以删除 autoprefixer
和 postcss-preset-env
,同时只保留自定义插件。这可以显着提高构建性能,因为 Parcel 的内置转译器比 PostCSS 快得多。
有关 Parcel 的内置转译支持的更多详细信息,请参阅 上面。
postcss-import
#默认情况下,Parcel 会独立地使用 PostCSS 转换每个 CSS 文件。但是,一些 PostCSS 插件(例如 postcss-custom-properties
)可能需要访问来自其他 @import
ed CSS 资产的声明。
在这些情况下,您可以使用 postcss-import
来一次性对整个捆绑包运行 PostCSS。 postcss-url
也应该用于确保在内联导入文件时 url()
引用被正确解析。
{
"plugins": {
"postcss-import": true,
"postcss-url": true,
"postcss-custom-properties": true
}
}
@import "./config/index.css";
html {
background-color: var(--varColor);
}
.icon {
width: 50px;
height: 50px;
background-image: var(--varIcon);
}
:root {
--varColor: red;
--varIcon: url("../icon.svg");
}
生产
#在生产模式下,Parcel 包含优化以减小代码的文件大小。有关此工作原理的更多详细信息,请参阅 生产。
缩小
#在生产模式下,Parcel 会自动缩小您的代码以减小捆绑包的文件大小。默认情况下,Parcel 使用 lightningcss 执行 CSS 缩小。
注意:在之前的版本中,Parcel 使用 cssnano 进行缩小。如果您的项目包含 cssnano 配置文件(例如 .cssnanorc
或 cssnano.config.json
),您可能会看到升级 Parcel 后不再应用它的警告。
在大多数情况下,您可以简单地删除 cssnano 配置文件并让 Parcel 处理缩小。但是,如果您确实依赖于此配置中的某些设置,并且希望继续使用 cssnano 而不是 lightningcss
进行缩小,您可以配置 Parcel 使用 @parcel/optimizer-cssnano
代替。
{
"extends": "@parcel/config-default",
"optimizers": {
"*.css": ["@parcel/optimizer-cssnano"]
}
}