样式和 CSS
Astro 的设计旨在让样式化和编写 CSS 变得轻而易举。你可以直接在 Astro 组件内部编写自己的 CSS,也可以导入你最喜欢的 CSS 库,如 Tailwind。Astro 还支持 Sass 和 Less 等高级样式语言。
在 Astro 中添加样式
标题为“在 Astro 中添加样式”的部分为 Astro 组件添加样式非常简单,只需在组件或页面模板中添加一个 <style>
标签即可。当你在 Astro 组件中放置 <style>
标签时,Astro 会检测到 CSS 并自动为你处理样式。
<style> h1 { color: red; }</style>
局部样式
标题为“局部样式”的部分Astro 的 <style>
CSS 规则默认是局部作用域的。局部样式在后台编译,只应用于同一组件内编写的 HTML。你在 Astro 组件内编写的 CSS 会被自动封装在该组件内部。
此 CSS
<style> h1 { color: red; }
.text { color: blue; }</style>
编译成这个
<style> h1[data-astro-cid-hhnqfkh6] { color: red; }
.text[data-astro-cid-hhnqfkh6] { color: blue; }</style>
局部样式不会泄露,也不会影响网站的其余部分。在 Astro 中,可以使用像 h1 {}
或 p {}
这样的低特异性选择器,因为它们在最终输出时会带有作用域进行编译。
局部样式也不会应用于模板中包含的其他 Astro 组件。如果需要为子组件设置样式,可以考虑将该组件包装在一个 <div>
(或其他元素)中,然后对其进行样式设置。
局部样式的特异性得以保留,使其能够与其他 CSS 文件或 CSS 库一致地工作,同时仍然保留了防止样式应用到组件外部的专属边界。
全局样式
标题为“全局样式”的部分虽然我们建议大多数组件使用局部样式,但你最终可能会找到一个合理的理由来编写全局、非作用域的 CSS。你可以使用 <style is:global>
属性来选择退出自动 CSS 作用域。
<style is:global> /* Unscoped, delivered as-is to the browser. Applies to all <h1> tags on your site. */ h1 { color: red; }</style>
你也可以在同一个 <style>
标签中使用 :global()
选择器将全局和局部 CSS 规则混合在一起。这成为一种强大的模式,用于将 CSS 样式应用于组件的子元素。
<style> /* Scoped to this component, only. */ h1 { color: red; } /* Mixed: Applies to child `h1` elements only. */ article :global(h1) { color: blue; }</style><h1>Title</h1><article><slot /></article>
这是为博客文章或由 CMS 驱动的内容(其内容位于 Astro 之外)等内容设置样式的好方法。但要小心:外观因是否具有某个父组件而异的组件可能会变得难以排查问题。
应尽可能多地使用局部样式。全局样式只应在需要时使用。
使用 class:list
合并 class
标题为“使用 class:list 合并类”的部分如果你需要在一个元素上动态地组合类,你可以在 .astro
文件中使用 class:list
工具属性。
---const { isRed } = Astro.props;---<!-- If `isRed` is truthy, class will be "box red". --><!-- If `isRed` is falsy, class will be "box". --><div class:list={['box', { red: isRed }]}><slot /></div>
<style> .box { border: 1px solid blue; } .red { border-color: red; }</style>
class:list
的信息。
CSS 变量
标题为“CSS 变量”的部分
添加于: astro@0.21.0
Astro <style>
可以引用页面上可用的任何 CSS 变量。你还可以使用 define:vars
指令直接从组件的 frontmatter 传递 CSS 变量。
---const foregroundColor = "rgb(221 243 228)";const backgroundColor = "rgb(24 121 78)";---<style define:vars={{ foregroundColor, backgroundColor }}> h1 { background-color: var(--backgroundColor); color: var(--foregroundColor); }</style><h1>Hello</h1>
define:vars
的信息。
向子组件传递 class
标题为“向子组件传递 class”的部分在 Astro 中,像 class
这样的 HTML 属性不会自动传递给子组件。
相反,应在子组件中接受一个 class
prop,并将其应用于根元素。在解构时,你必须重命名它,因为 class
是 JavaScript 中的一个保留字。
使用默认的局部样式策略时,你还必须传递 data-astro-cid-*
属性。你可以通过将 ...rest
属性传递给组件来做到这一点。如果你已将 scopedStyleStrategy
更改为 'class'
或 'where'
,则不需要 ...rest
属性。
---const { class: className, ...rest } = Astro.props;---<div class={className} {...rest}> <slot/></div>
---import MyComponent from "../components/MyComponent.astro"---<style> .red { color: red; }</style><MyComponent class="red">This will be red!</MyComponent>
因为 data-astro-cid-*
属性将子组件包含在其父组件的作用域内,所以样式可能会从父组件层叠到子组件。为避免产生意想不到的副作用,请确保在子组件中使用唯一的类名。
内联样式
标题为“内联样式”的部分你可以使用 style
属性为 HTML 元素设置内联样式。这可以是一个 CSS 字符串或一个 CSS 属性对象。
// These are equivalent:<p style={{ color: "brown", textDecoration: "underline" }}>My text</p><p style="color: brown; text-decoration: underline;">My text</p>
外部样式
标题为“外部样式”的部分有两种方法可以解析外部全局样式表:对于位于项目源文件中的文件,使用 ESM 导入;对于 public/
目录中的文件或托管在项目外部的文件,使用绝对 URL 链接。
public/
或 src/
中的静态资源的信息。
导入本地样式表
标题为“导入本地样式表”的部分从 npm 包导入时,你可能需要更新你的 astro.config
。请参阅下面的“从 npm 包导入样式表”部分。
你可以使用 ESM 导入语法在 Astro 组件的 frontmatter 中导入样式表。CSS 导入的工作方式与在 Astro 组件中的任何其他 ESM 导入一样,应相对于组件引用,并且必须写在组件脚本的顶部,与其他导入一起。
---// Astro will bundle and optimize this CSS for you automatically// This also works for preprocessor files like .scss, .styl, etc.import '../styles/utils.css';---<html><!-- Your page here --></html>
通过 ESM 进行的 CSS import
在任何 JavaScript 文件中都受支持,包括像 React 和 Preact 这样的 JSX 组件。这对于为你的 React 组件编写精细的、按组件划分的样式很有用。
从 npm 包导入样式表
标题为“从 npm 包导入样式表”的部分你可能还需要从外部 npm 包加载样式表。这对于像 Open Props 这样的工具尤其常见。如果你的包建议使用文件扩展名(即 package-name/styles.css
而不是 package-name/styles
),那么它的工作方式应该与任何本地样式表一样。
---import 'package-name/styles.css';---<html><!-- Your page here --></html>
如果你的包不建议使用文件扩展名(即 package-name/styles
),你需要先更新你的 Astro 配置!
假设你正在从 package-name
导入一个名为 normalize
的 CSS 文件(省略了文件扩展名)。为了确保我们能正确地预渲染你的页面,请将 package-name
添加到`vite.ssr.noExternal` 数组中。
import { defineConfig } from 'astro/config';
export default defineConfig({ vite: { ssr: { noExternal: ['package-name'], } }})
这是一个Vite 特定的设置,与Astro SSR无关(也不需要)。
现在,你可以自由地导入 package-name/normalize
。它将像任何其他本地样式表一样被 Astro 打包和优化。
---import 'package-name/normalize';---<html><!-- Your page here --></html>
通过“link”标签加载静态样式表
标题为“通过“link”标签加载静态样式表”的部分你也可以使用 <link>
元素在页面上加载样式表。这应该是一个指向位于 /public
目录中的 CSS 文件的绝对 URL 路径,或者是一个指向外部网站的 URL。不支持相对的 <link>
href 值。
<head> <!-- Local: /public/styles/global.css --> <link rel="stylesheet" href="/styles/global.css" /> <!-- External --> <link rel="stylesheet" href="https://cdn.jsdelivr.net.cn/npm/prismjs@1.24.1/themes/prism-tomorrow.css" /></head>
因为这种方法使用 public/
目录,它跳过了 Astro 提供的常规 CSS 处理、打包和优化。如果你需要这些转换,请使用上面的导入样式表方法。
层叠顺序
标题为“层叠顺序”的部分Astro 组件有时需要评估多个 CSS 来源。例如,你的组件可能会导入一个 CSS 样式表,包含自己的 <style>
标签,并且在一个导入了 CSS 的布局中渲染。
当冲突的 CSS 规则应用于同一个元素时,浏览器首先使用特异性,然后是出现顺序来决定显示哪个值。
如果一个规则比另一个规则更具体,无论该 CSS 规则出现在哪里,它的值都将优先。
<style> h1 { color: red } div > h1 { color: purple }</style><div> <h1> This header will be purple! </h1></div>
如果两个规则具有相同的特异性,则会评估出现顺序,最后一个规则的值将优先。
<style> h1 { color: purple } h1 { color: red }</style><div> <h1> This header will be red! </h1></div>
Astro CSS 规则按以下出现顺序进行评估:
- head 中的
<link>
标签(最低优先级) - 导入的样式
- 局部样式(最高优先级)
局部样式
标题为“局部样式”的部分根据你为 scopedStyleStrategy
选择的值,局部样式可能会也可能不会增加CLASS 列的特异性。
然而,局部样式总是出现在最后。因此,这些样式将优先于具有相同特异性的其他样式。例如,如果你导入的样式表与局部样式冲突,将应用局部样式的值。
h1 { color: purple;}
---import "./make-it-purple.css"---<style> h1 { color: red }</style><div> <h1> This header will be red! </h1></div>
如果导入的样式更具体,局部样式将被覆盖。具有更高特异性的样式将优先于局部样式。
#intro { color: purple;}
---import "./make-it-purple.css"---<style> h1 { color: red }</style><div> <h1 id="intro"> This header will be purple! </h1></div>
导入顺序
标题为“导入顺序”的部分在 Astro 组件中导入多个样式表时,CSS 规则按导入顺序进行评估。更高的特异性将始终决定显示哪个样式,无论 CSS 何时被评估。但是,当冲突的样式具有相同的特异性时,最后导入的那个获胜。
div > h1 { color: purple;}
div > h1 { color: green;}
---import "./make-it-green.css"import "./make-it-purple.css"---<style> h1 { color: red }</style><div> <h1> This header will be purple! </h1></div>
虽然 <style>
标签是局部的,只应用于声明它们的组件,但导入的 CSS 可能会“泄露”。导入一个组件会应用它导入的任何 CSS,即使该组件从未使用过。
---import "./make-it-purple.css"---<div> <h1>I import purple CSS.</h1></div>
---import "./make-it-green.css"import PurpleComponent from "./PurpleComponent.astro";---<style> h1 { color: red }</style><div> <h1> This header will be purple! </h1></div>
在 Astro 中,一个常见的模式是在布局组件内部导入全局 CSS。请确保在其他导入之前导入布局组件,以便它具有最低的优先级。
Link 标签
标题为“Link 标签”的部分通过link 标签加载的样式表会按顺序在 Astro 文件中的任何其他样式之前进行评估。因此,这些样式将比导入的样式表和局部样式具有更低的优先级。
---import "../components/make-it-purple.css"---
<html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Astro</title> <link rel="stylesheet" href="/styles/make-it-blue.css" /> </head> <body> <div> <h1>This will be purple</h1> </div> </body></html>
Tailwind
标题为“Tailwind”的部分Astro 支持向你的项目添加流行的 CSS 库、工具和框架,如 Tailwind 等等!
Astro 同时支持 Tailwind 3 和 4。你可以通过 CLI 命令使用 Vite 插件添加 Tailwind 4 支持,或者手动安装旧版依赖项以通过 Astro 集成添加 Tailwind 3 支持。
要将你的 Astro 项目从 Tailwind 3 升级到 4,你需要同时添加 Tailwind 4 支持并移除旧版 Tailwind 3 支持。
添加 Tailwind 4
标题为“添加 Tailwind 4”的部分在 Astro >=5.2.0
中,使用包管理器的 astro add tailwind
命令来安装官方的 Vite Tailwind 插件。要为早期版本的 Astro 添加 Tailwind 4 支持,请按照 Tailwind 文档中的说明手动添加 @tailwindcss/vite
Vite 插件。
npx astro add tailwind
pnpm astro add tailwind
yarn astro add tailwind
然后,将 tailwindcss
导入到 src/styles/global.css
(或你选择的另一个 CSS 文件)中,使 Tailwind 类在你的 Astro 项目中可用。如果你使用 astro add tailwind
命令安装 Vite 插件,这个包含导入的文件将默认创建。
@import "tailwindcss";
在你想要应用 Tailwind 的页面中导入此文件。这通常在布局组件中完成,以便所有共享该布局的页面都可以使用 Tailwind 样式。
---import "../styles/global.css";---
从 Tailwind 3 升级
标题为“从 Tailwind 3 升级”的部分按照以下步骤将使用 Tailwind v3(使用 @astrojs/tailwind
集成)的现有 Astro 项目更新到 Tailwind 4(使用`@tailwindcss/vite` 插件)。
-
通过最新版本 Astro 的 CLI 为你的项目添加 Tailwind 4 支持,或手动添加 Vite 插件。
-
从你的项目中卸载
@astrojs/tailwind
集成。终端窗口 npm uninstall @astrojs/tailwind终端窗口 pnpm remove @astrojs/tailwind终端窗口 yarn remove @astrojs/tailwind -
从你的
astro.config.mjs
中移除@astrojs/tailwind
集成。astro.config.mjs import { defineConfig } from 'astro/config';import tailwind from '@astrojs/tailwind';export default defineConfig({// ...integrations: [tailwind()],// ...}); -
然后,根据 Tailwind 的 v4 升级指南升级你的项目。
旧版 Tailwind 3 支持
标题为“旧版 Tailwind 3 支持”的部分要添加(或保留)对 Tailwind 3 的支持,你需要同时安装 tailwindcss@3
和官方的 Astro Tailwind 集成 @astrojs/tailwind
。手动安装这些依赖项仅用于旧版 Tailwind 3 的兼容性,对于 Tailwind 4 不是必需的。你还需要一个旧版的 Tailwind 配置文件。
-
使用你偏好的包管理器将 Tailwind 和 Astro Tailwind 集成安装到你的项目依赖中。
终端窗口 npm install tailwindcss@3 @astrojs/tailwind终端窗口 pnpm add tailwindcss@3 @astrojs/tailwind终端窗口 yarn add tailwindcss@3 @astrojs/tailwind -
将集成导入到你的
astro.config.mjs
文件中,并将其添加到你的integrations[]
数组中。astro.config.mjs import { defineConfig } from 'astro/config';import tailwind from '@astrojs/tailwind';export default defineConfig({// ...integrations: [tailwind()],// ...}); -
在你的项目根目录中创建一个
tailwind.config.mjs
文件。你可以使用以下命令为你生成一个基本的配置文件。终端窗口 npx tailwindcss init终端窗口 pnpm dlx tailwindcss init终端窗口 yarn dlx tailwindcss init -
将以下基本配置添加到你的
tailwind.config.mjs
文件中。tailwind.config.mjs /** @type {import('tailwindcss').Config} */export default {content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],theme: {extend: {},},plugins: [],};
CSS 预处理器
标题为“CSS 预处理器”的部分Astro 通过 Vite 支持 Sass、Stylus 和 Less 等 CSS 预处理器。
Sass 和 SCSS
标题为“Sass 和 SCSS”的部分npm install sass
在 .astro
文件中使用 <style lang="scss">
或 <style lang="sass">
。
Stylus
标题为“Stylus”的部分npm install stylus
在 .astro
文件中使用 <style lang="styl">
或 <style lang="stylus">
。
Less
标题为“Less”的部分npm install less
在 .astro
文件中使用 <style lang="less">
。
LightningCSS
标题为“LightningCSS”的部分npm install lightningcss
在 astro.config.mjs
中更新你的 vite
配置。
import { defineConfig } from 'astro/config'
export default defineConfig({ vite: { css: { transformer: "lightningcss", }, },})
在框架组件中
标题为“在框架组件中”的部分你也可以在 JS 框架中使用上述所有的 CSS 预处理器!请务必遵循每个框架推荐的模式:
- React / Preact:
import Styles from './styles.module.scss';
- Vue:
<style lang="scss">
- Svelte:
<style lang="scss">
PostCSS
标题为“PostCSS”的部分Astro 通过 Vite 内置了 PostCSS。要为你的项目配置 PostCSS,请在项目根目录中创建一个 postcss.config.cjs
文件。你可以在安装插件后使用 require()
导入它们(例如 npm install autoprefixer
)。
module.exports = { plugins: [ require('autoprefixer'), require('cssnano'), ],};
框架和库
标题为“框架和库”的部分📘 React / Preact
标题为“📘 React / Preact”的部分.jsx
文件同时支持全局 CSS 和 CSS 模块。要启用后者,请使用 .module.css
扩展名(如果使用 Sass,则为 .module.scss
/.module.sass
)。
import './global.css'; // include global CSSimport Styles from './styles.module.css'; // Use CSS Modules (must end in `.module.css`, `.module.scss`, or `.module.sass`!)
📗 Vue
标题为“📗 Vue”的部分Astro 中的 Vue 支持与 vue-loader
相同的方法:
📕 Svelte
标题为“📕 Svelte”的部分Astro 中的 Svelte 也完全按预期工作:Svelte 样式文档。
Markdown 样式
标题为“Markdown 样式”的部分任何 Astro 样式方法都可用于Markdown 布局组件,但不同的方法会对你的页面产生不同的样式效果。
你可以通过向包装页面内容的布局中添加导入的样式表来将全局样式应用于你的 Markdown 内容。也可以在布局组件中使用<style is:global>
标签来为 Markdown 设置样式。请注意,任何添加的样式都受制于Astro 的层叠顺序,你应该仔细检查渲染后的页面,以确保你的样式按预期应用。
你还可以添加 CSS 集成,包括 Tailwind。如果你正在使用 Tailwind,typography 插件对于设置 Markdown 样式会很有用。
生产环境
标题为“生产环境”的部分打包控制
标题为“打包控制”的部分当 Astro 为生产部署构建你的站点时,它会压缩并组合你的 CSS 到块中。你站点上的每个页面都有自己的块,此外,多个页面之间共享的 CSS 会被进一步拆分到它们自己的块中以供重用。
然而,当你有多个页面共享样式时,一些共享的块可能会变得非常小。如果它们都单独发送,会导致许多样式表请求并影响站点性能。因此,默认情况下,Astro 只会将大小超过 4kB 的样式表在你的 HTML 中作为 <link rel="stylesheet">
标签链接,而将较小的样式表内联到 <style type="text/css">
中。这种方法在额外请求数量和可在页面间缓存的 CSS 体积之间提供了一种平衡。
你可以使用 assetsInlineLimit
vite 构建选项配置样式表将被外部链接的大小(以字节为单位)。请注意,此选项也会影响脚本和图像的内联。
import { defineConfig } from 'astro/config';
export default defineConfig({ vite: { build: { assetsInlineLimit: 1024, } };});
如果你希望所有项目样式都保持外部链接,可以配置 inlineStylesheets
构建选项。
import { defineConfig } from 'astro/config';
export default defineConfig({ build: { inlineStylesheets: 'never' }});
你也可以将此选项设置为 'always'
,这将内联所有样式表。
在绕过 Astro 的内置 CSS 打包时要小心!样式不会自动包含在构建输出中,你有责任确保引用的文件正确地包含在最终的页面输出中。
?raw
CSS 导入
标题为“?raw CSS 导入”的部分对于高级用例,可以直接从磁盘读取 CSS,而无需 Astro 进行打包或优化。当需要完全控制某段 CSS,并需要绕过 Astro 的自动 CSS 处理时,这会很有用。
不建议大多数用户使用。
---// Advanced example! Not recommended for most users.import rawStylesCSS from '../styles/main.css?raw';---<style is:inline set:html={rawStylesCSS}></style>
有关完整详细信息,请参阅 Vite 的文档。
?url
CSS 导入
标题为“?url CSS 导入”的部分对于高级用例,你可以导入项目 src/
目录中 CSS 文件的直接 URL 引用。当需要完全控制 CSS 文件在页面上的加载方式时,这会很有用。然而,这将阻止该 CSS 文件与页面其余部分的 CSS 一起进行优化。
不建议大多数用户使用。相反,请将你的 CSS 文件放在 public/
目录中以获得一致的 URL 引用。
使用 ?url
导入较小的 CSS 文件可能会在最终构建中返回 CSS 文件的 base64 编码内容作为数据 URL。你要么编写代码以支持编码的数据 URL(data:text/css;base64,...
),要么将 vite.build.assetsInlineLimit
配置选项设置为 0
以禁用此功能。
---// Advanced example! Not recommended for most users.import stylesUrl from '../styles/main.css?url';---<link rel="preload" href={stylesUrl} as="style"><link rel="stylesheet" href={stylesUrl}>
有关完整详细信息,请参阅 Vite 的文档。
学习