样式 & CSS

Astro 的设计为了使设计和编写 CSS 变得轻而易举。直接在 Astro 组件中编写你自己的 CSS,或者导入你最喜欢的 CSS 库,如 Tailwind 外。也支持高级样式设计语言,如 SassLess

为 Astro 组件设计样式,就像在你的组件或页面模板上添加 <style> 标签一样容易。当你在 Astro 组件内置了 <style> 标签时,Astro 就会自动检测 CSS 并开始为你处理样式。

<style>
  h1 { color: red; }
</style>

Astro <style> 标签内的 CSS 规则默认自动限定范围。作用域样式在幕后编译,只适用于写在同一组件内的 HTML。你在 Astro 组件中编写的 CSS 会自动封装在该组件中。

<style>
-  h1 { color: red; }
+  h1.astro-HHNQFKH6 { color: red; }
-  .text { color: blue; }
+  .text.astro-HHNQFKH6 { color: blue; }
</style>

作用域样式不会泄漏,也不会影响你网站的其他部分。在 Astro 中,可以使用像 h1 {}p {} 这样的低特定性选择器,因为在最终输出中它们与作用域一起被编译。

作用域样式也不适用于模板内的其他 Astro 组件。如果你需要修改子组件的样式,可以考虑将该组件包裹在 <div>(或其他元素)中,然后你就可以对其编写样式了。

虽然我们推荐大多数组件使用范围化的样式,但有时你可能有必要使用全局的、非限定范围的 CSS。你可以通过 <style is:global> 属性选择不自动限定 CSS 范围。

<style is:global>
  /* 无范围,按原样传递给浏览器。
     适用于网站上的所有 <h1> 标签 */
  h1 { color: red; }
</style>

你也可以使用 :global() 选择器在同一个 <style> 标签中混合全局和作用域 CSS 规则。这可以将 CSS 样式应用于子组件。

<style>
  /* 仅适用于作用域 */
  h1 { color: red; }
  /* 混合,仅适用于子 `h1` 元素 */
  article :global(h1) {
    color: blue;
  }
</style>
<h1>Title</h1>
<article><slot /></article>

它适合用于像博客文章,或由 CMS 驱动的内容文档,这些内容在 Astro 之外的样式。但要注意会因为某个父级组件有无而导致样式不同会使得很难进行错误排查。

应尽可能多的使用作用域样式,而仅在必要时使用全局样式。

添加于: v0.21.0

Astro <style> 可以引用页面上任何可用的 CSS 变量。你也可以使用 define:vars 指令直接通过组件传递 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 的信息。

有两种使用外部全局样式表的方法:项目源文件中使用 ESM 导入;使用绝对链接引用 public/ 目录中的文件或托管于别处的文件。

📚 阅读更多关于使用位于 public/src/静态资源

你可以在 Astro 组件中使用 ESM 导入语法显式导入样式表。CSS 导入方式与 Astro 组件中的其他 ESM 导入一样,它应该基于组件进行引用,并且与其他导入一样必须位于组件脚本顶层

---
// Astro 会自动为你捆绑和优化这些CSS。
// 这也适用于预处理器文件,如 .scss、.styl 等。
import '../styles/utils.css';
---
<html><!-- Your page here --></html>

任何 JavaScript 文件都支持通过 ESM import导入 CSS,包括像 React 和 Preact 这样的 JSX 组件。这有助于为 React 组件编写细化的,具有针对性的样式

你也可能需要从外部 npm 包中加载样式表。它常用于像导入 Open Props 这样的工具类。如果你的包建议使用文件扩展名(即 package-name/styles.css 而不是 package-name/styles),那么它的行为应该与本地样式表一致:

src/pages/random-page.astro
---
import 'package-name/styles.css';
---
<html><!-- Your page here --></html>

如果你所用的包不建议使用文件扩展名(即 包名/样式),那么你就需要先更新 Astro 配置

假设你从 package-name 导入名为 normalize 的 CSS 文件(省略文件扩展名)。为了确保我们能正确地预渲染你的页面,需要把package-name 添加到 vite.ssr.noExternal 数组中。

astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  vite: {
    ssr: {
      noExternal: ['package-name'],
    }
  }
})

现在,你可以导入 package-name/normalize 了。Astro 将对其进行捆绑和优化,就像任何其他本地样式表一样。

src/pages/random-page.astro
---
import 'package-name/normalize';
---
<html><!-- Your page here --></html>
Section titled 通过 link 标签加载静态样式表

你也可以使用 <link> 元素在页面上加载样式表。它是应该位于 /public 目录下的 CSS 文件的绝对路径,或者是外部网站的链接。不支持使用相对路径的 <link> href 值。

<head>
  <!-- 本地:/public/styles/global.css -->
  <link rel="stylesheet" href="/styles/global.css" />
  <!-- 外部 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css">
</head>

因为这种方法使用 public/ 目录,它跳过了 Astro 提供的 CSS 处理、捆绑和压缩。如果你需要这些转换,请使用上面的导入样式表方法。

Astro 支持在项目中添加流行的 CSS 库、工具和框架,如 Tailwind 和其他库!

📚 参见集成指南,了解安装、导入和配置这些集成的说明。

Astro 支持通过 Vite 使用 CSS 预处理器,如 SassStylusLess,。

npm install -D sass

.astro 文件中使用 <style lang="scss"><style lang="sass">

npm install -D stylus

.astro 文件中使用 <style lang="styl"><style lang="stylus">

npm install -D less

.astro 文件中使用 <style lang="less">

你也可以在 JS 框架内使用上述所有的 CSS 预处理程序! 请务必遵循每个框架推荐的模式。

  • React / Preact: import Styles from './styles.module.scss';
  • Vue: <style lang="scss">
  • Svelte: <style lang="scss">

Astro 内置了 PostCSS,作为 Vite 的一部分。要为你的项目配置 PostCSS,在项目根部创建 postcss.config.js 文件。然后你就你可以在安装插件后使用 require() 导入插件(例如 npm i autoprefixer)。

./postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer'),
    require('cssnano'),
  ],
};

.jsx 文件同时支持全局 CSS 和 CSS 模块。要启用后者,请使用 .module.css 扩展名(如果使用 Sass 则是 .module.scss/.module.sass )。

import './global.css'; //包括全局CSS
import Styles from './styles.module.css'; // 使用 CSS 模块(必须以 `.module.css`、`.module.scss` 或 `.module.sass` 结尾!)

Astro 中的 Vue 支持与 vue-loader 一样的方法。

Astro 中的 Svelte 也完全按照预期工作。Svelte Styling Docs

对于高级用例,CSS 可以直接从磁盘上读取,而 Astro 不进行捆绑或压缩。当你需要完全控制某些 CSS 片段,并需要绕过 Astro 的自动 CSS 处理时,这可能有用的。

对于大多数用户来说,不建议这样做:

---
// 高级用例! 不建议大多数用户使用
import rawStylesCSS from '../styles/main.css?raw';
---
<style is:inline set:html={rawStylesCSS}></style>

完整的细节见Vite的文档

一个高级用例,你可以在你的项目 src/ 目录中直接导入 CSS 文件链接。当你需要完全控制 CSS 文件在页面上的加载方式时可能有用。然而,这将阻止该 CSS 文件和你的页面上的其他 CSS 进行优化。

对于大多数用户来说,不建议这样做。相反,将 CSS 文件放在 public/ 内,你可以获得一致的链接。

---
// 高级用例! 不建议大多数用户使用
import stylesUrl from '../styles/main.css?url';
---
<link rel="preload" href={stylesUrl} as="style">
<link rel="stylesheet" href={stylesUrl}>

完整的细节见 Vite 文档