Skip to content

样式和 CSS

Astro 旨在让 CSS 样式设计和编写变得轻而易举。直接在 Astro 组件中编写你自己的 CSS 或导入你最喜欢的 CSS 库,例如 Tailwind。还支持 SassLess 等高级样式语言。

¥Astro was designed to make styling and writing CSS a breeze. Write your own CSS directly inside of an Astro component or import your favorite CSS library like Tailwind. Advanced styling languages like Sass and Less are also supported.

¥Styling in Astro

设置 Astro 组件的样式就像向组件或页面模板添加 <style> 标签一样简单。当你将 <style> 标签放入 Astro 组件内时,Astro 将自动检测 CSS 并为你处理样式。

¥Styling an Astro component is as easy as adding a <style> tag to your component or page template. When you place a <style> tag inside of an Astro component, Astro will detect the CSS and handle your styles for you, automatically.

src/components/MyComponent.astro
<style>
h1 { color: red; }
</style>

¥Scoped Styles

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

¥Astro <style> CSS rules are automatically scoped by default. Scoped styles are compiled behind-the-scenes to only apply to HTML written inside of that same component. The CSS that you write inside of an Astro component is automatically encapsulated inside of that component.

这个 CSS:

¥This CSS:

src/pages/index.astro
<style>
h1 {
color: red;
}
.text {
color: blue;
}
</style>

编译为:

¥Compiles to this:

<style>
h1[data-astro-cid-hhnqfkh6] {
color: red;
}
.text[data-astro-cid-hhnqfkh6] {
color: blue;
}
</style>

范围样式不会泄漏,也不会影响网站的其他部分。在 Astro 中,可以使用 h1 {}p {} 等低特异性选择器,因为它们将在最终输出中使用范围进行编译。

¥Scoped styles don’t leak and won’t impact the rest of your site. In Astro, it is okay to use low-specificity selectors like h1 {} or p {} because they will be compiled with scopes in the final output.

范围样式也不适用于模板内包含的其他 Astro 组件。如果你需要设置子组件的样式,请考虑将该组件封装在 <div>(或其他元素)中,然后你可以设置样式。

¥Scoped styles also won’t apply to other Astro components contained inside of your template. If you need to style a child component, consider wrapping that component in a <div> (or other element) that you can then style.

范围样式的特殊性得以保留,使它们能够与其他 CSS 文件或 CSS 库一致地工作,同时仍然保留防止样式在组件外部应用的排他边界。

¥The specificity of scoped styles is preserved, allowing them to work consistently alongside other CSS files or CSS libraries while still preserving the exclusive boundaries that prevent styles from applying outside the component.

¥Global Styles

虽然我们建议大多数组件使用作用域样式,但你最终可能会找到编写全局、无作用域 CSS 的正当理由。你可以使用 <style is:global> 属性选择退出自动 CSS 作用域。

¥While we recommend scoped styles for most components, you may eventually find a valid reason to write global, unscoped CSS. You can opt-out of automatic CSS scoping with the <style is:global> attribute.

src/components/GlobalStyles.astro
<style is:global>
/* Unscoped, delivered as-is to the browser.
Applies to all <h1> tags on your site. */
h1 { color: red; }
</style>

你还可以使用 :global() 选择器在同一 <style> 标记中混合全局和范围 CSS 规则。这成为将 CSS 样式应用于组件子组件的强大模式。

¥You can also mix global & scoped CSS rules together in the same <style> tag using the :global() selector. This becomes a powerful pattern for applying CSS styles to children of your component.

src/components/MixedStyles.astro
<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 之外)。不过要小心:外观因是否具有特定父组件而不同的组件可能会变得难以排除故障。

¥This is a great way to style things like blog posts, or documents with CMS-powered content where the contents live outside of Astro. But be careful: components whose appearance differs based on whether or not they have a certain parent component can become difficult to troubleshoot.

应尽可能频繁地使用范围样式。全局样式应仅根据需要使用。

¥Scoped styles should be used as often as possible. Global styles should be used only as-needed.

¥Combining classes with class:list

如果需要动态组合元素上的类,可以在 .astro 文件中使用 class:list 实用程序属性。

¥If you need to combine classes on an element dynamically, you can use the class:list utility attribute in .astro files.

src/components/ClassList.astro
---
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>
See our directives reference page to learn more about class:list.

¥CSS Variables

Added in: astro@0.21.0

Astro <style> 可以引用页面上可用的任何 CSS 变量。你还可以使用 define:vars 指令直接从组件 frontmatter 传递 CSS 变量。

¥The Astro <style> can reference any CSS variables available on the page. You can also pass CSS variables directly from your component frontmatter using the define:vars directive.

src/components/DefineVars.astro
---
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>
See our directives reference page to learn more about define:vars.

¥Passing a class to a child component

在 Astro 中,像 class 这样的 HTML 属性不会自动传递给子组件。

¥In Astro, HTML attributes like class do not automatically pass through to child components.

相反,在子组件中接受 class 属性并将其应用到根元素。解构时,必须重命名,因为 class 在 JavaScript 中是 保留字

¥Instead, accept a class prop in the child component and apply it to the root element. When destructuring, you must rename it, because class is a reserved word in JavaScript.

使用默认的作用域样式策略,你还必须传递 data-astro-cid-* 属性。你可以通过将 props 的 ...rest 传递给组件来完成此操作。如果你已将 scopedStyleStrategy 更改为 'class''where',则不需要 ...rest 属性。

¥Using the default scoped style strategy, you must also pass the data-astro-cid-* attribute. You can do this by passing the ...rest of the props to the component. If you have changed scopedStyleStrategy to 'class' or 'where', the ...rest prop is not necessary.

src/components/MyComponent.astro
---
const { class: className, ...rest } = Astro.props;
---
<div class={className} {...rest}>
<slot/>
</div>
src/pages/index.astro
---
import MyComponent from "../components/MyComponent.astro"
---
<style>
.red {
color: red;
}
</style>
<MyComponent class="red">This will be red!</MyComponent>

¥Inline styles

你可以使用 style 属性来内联 HTML 元素的样式。这可以是 CSS 字符串或 CSS 属性的对象:

¥You can style HTML elements inline using the style attribute. This can be a CSS string or an object of CSS properties:

src/pages/index.astro
// These are equivalent:
<p style={{ color: "brown", textDecoration: "underline" }}>My text</p>
<p style="color: brown; text-decoration: underline;">My text</p>

¥External Styles

有两种方法可以解决外部全局样式表:位于项目源中的文件的 ESM 导入,以及 public/ 目录中或项目外部托管的文件的绝对 URL 链接。

¥There are two ways to resolve external global stylesheets: an ESM import for files located within your project source, and an absolute URL link for files in your public/ directory, or hosted outside of your project.

Read more about using static assets located in public/ or src/.

¥Import a local stylesheet

你可以使用 ESM 导入语法在 Astro 组件 frontmatter 中导入样式表。CSS 导入的工作方式类似于 any other ESM import in an Astro component,它应该作为相对于组件的引用,并且必须与任何其他导入一起写在组件脚本的顶部。

¥You can import stylesheets in your Astro component frontmatter using ESM import syntax. CSS imports work like any other ESM import in an Astro component, which should be referenced as relative to the component and must be written at the top of your component script, with any other imports.

src/pages/index.astro
---
// 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>

任何 JavaScript 文件内部都支持通过 ESM 的 CSS import,包括 React 和 Preact 等 JSX 组件。这对于为 React 组件编写细粒度的、每个组件的样式非常有用。

¥CSS import via ESM are supported inside of any JavaScript file, including JSX components like React & Preact. This can be useful for writing granular, per-component styles for your React components.

¥Import a stylesheet from an npm package

你可能还需要从外部 npm 包加载样式表。这对于像 打开属性 这样的实用工具来说尤其常见。如果你的软件包建议使用文件扩展名(即 package-name/styles.css 而不是 package-name/styles),这应该像任何本地样式表一样工作:

¥You may also need to load stylesheets from an external npm package. This is especially common for utilities like Open Props. If your package recommends using a file extension (i.e. package-name/styles.css instead of package-name/styles), this should work like any local stylesheet:

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

如果你的软件包不建议使用文件扩展名(即 package-name/styles),你需要先更新你的 Astro 配置!

¥If your package does not suggest using a file extension (i.e. package-name/styles), you’ll need to update your Astro config first!

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

¥Say you are importing a CSS file from package-name called normalize (with the file extension omitted). To ensure we can prerender your page correctly, add package-name to the vite.ssr.noExternal array:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
ssr: {
noExternal: ['package-name'],
}
}
})

现在,你可以自由导入 package-name/normalize。这将像任何其他本地样式表一样由 Astro 进行打包和优化。

¥Now, you are free to import package-name/normalize. This will be bundled and optimized by Astro like any other local stylesheet.

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

¥Load a static stylesheet via “link” tags

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

¥You can also use the <link> element to load a stylesheet on the page. This should be an absolute URL path to a CSS file located in your /public directory, or an URL to an external website. Relative <link> href values are not supported.

src/pages/index.astro
<head>
<!-- Local: /public/styles/global.css -->
<link rel="stylesheet" href="/styles/global.css" />
<!-- External -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css" />
</head>

由于此方法使用 public/ 目录,因此它跳过 Astro 提供的正常 CSS 处理、打包和优化。如果你需要这些转换,请使用上面的 导入样式表 方法。

¥Because this approach uses the public/ directory, it skips the normal CSS processing, bundling and optimizations that are provided by Astro. If you need these transformations, use the Import a Stylesheet method above.

¥Cascading Order

Astro 组件有时必须评估多个 CSS 源。例如,你的组件可能会导入 CSS 样式表,包含其自己的 <style> 标记,并在导入 CSS 的布局内渲染。

¥Astro components will sometimes have to evaluate multiple sources of CSS. For example, your component might import a CSS stylesheet, include its own <style> tag, and be rendered inside a layout that imports CSS.

当冲突的 CSS 规则应用于同一元素时,浏览器首先使用特异性,然后使用外观顺序来确定要显示的值。

¥When conflicting CSS rules apply to the same element, browsers first use specificity and then order of appearance to determine which value to show.

如果一条规则比另一条规则更具体,则无论 CSS 规则出现在何处,其值都将优先:

¥If one rule is more specific than another, no matter where the CSS rule appears, its value will take precedence:

src/components/MyComponent.astro
<style>
h1 { color: red }
div > h1 {
color: purple
}
</style>
<div>
<h1>
This header will be purple!
</h1>
</div>

如果两个规则具有相同的特异性,则评估出现的顺序,最后一个规则的值将优先:

¥If two rules have the same specificity, then the order of appearance is evaluated, and the last rule’s value will take precedence:

src/components/MyComponent.astro
<style>
h1 { color: purple }
h1 { color: red }
</style>
<div>
<h1>
This header will be red!
</h1>
</div>

Astro CSS 规则按以下出现顺序进行评估:

¥Astro CSS rules are evaluated in this order of appearance:

  • 头部中的 <link> 标签(最低优先级)

  • 导入样式

  • 范围样式(最高优先级)

¥Scoped Styles

使用 范围样式 不会增加 CSS 的特殊性,但它们在出现的顺序中总是排在最后。因此,它们将优先于具有相同特性的其他样式。例如,如果你导入与作用域样式冲突的样式表,则作用域样式的值将适用:

¥Using scoped styles does not increase the specificity of your CSS, but they will always come last in the order of appearance. They will therefore take precedence over other styles of the same specificity. For example, if you import a stylesheet that conflicts with a scoped style, the scoped style’s value will apply:

src/components/make-it-purple.css
h1 {
color: purple;
}
src/components/MyComponent.astro
---
import "./make-it-purple.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
This header will be red!
</h1>
</div>

如果你使导入的样式更加具体,它将比作用域样式具有更高的优先级:

¥If you make the imported style more specific, it will have higher precedence over the scoped style:

src/components/make-it-purple.css
div > h1 {
color: purple;
}
src/components/MyComponent.astro
---
import "./make-it-purple.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
This header will be purple!
</h1>
</div>

¥Import Order

在 Astro 组件中导入多个样式表时,CSS 规则将按照导入的顺序进行评估。无论何时评估 CSS,更高的特异性始终会决定要显示的样式。但是,当冲突的样式具有相同的特异性时,最后导入的样式获胜:

¥When importing multiple stylesheets in an Astro component, the CSS rules are evaluated in the order that they are imported. A higher specificity will always determine which styles to show, no matter when the CSS is evaluated. But, when conflicting styles have the same specificity, the last one imported wins:

src/components/make-it-purple.css
div > h1 {
color: purple;
}
src/components/make-it-green.css
div > h1 {
color: green;
}
src/components/MyComponent.astro
---
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 可以 “leak”。导入组件会应用它导入的任何 CSS,即使该组件从未使用过:

¥While <style> tags are scoped and only apply to the component that declares them, imported CSS can “leak”. Importing a component applies any CSS it imports, even if the component is never used:

src/components/PurpleComponent.astro
---
import "./make-it-purple.css"
---
<div>
<h1>I import purple CSS.</h1>
</div>
src/components/MyComponent.astro
---
import "./make-it-green.css"
import PurpleComponent from "./PurpleComponent.astro";
---
<style>
h1 { color: red }
</style>
<div>
<h1>
This header will be purple!
</h1>
</div>

¥Link Tags

通过 链接标签 加载的样式表将在 Astro 文件中的任何其他样式之前按顺序进行评估。因此,这些样式的优先级低于导入的样式表和作用域样式:

¥Style sheets loaded via link tags are evaluated in order, before any other styles in an Astro file. Therefore, these styles will have lower precedence than imported stylesheets and scoped styles:

src/pages/index.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>

¥CSS Integrations

Astro 支持将流行的 CSS 库、工具和框架添加到你的项目中,例如 Tailwind 等!

¥Astro comes with support for adding popular CSS libraries, tools, and frameworks to your project like Tailwind and more!

要在项目中使用 Tailwind,请使用包管理器的 astro add 命令安装官方 Astro Tailwind 集成

¥To use Tailwind in your project, install the official Astro Tailwind integration using the astro add command for your package manager:

Terminal window
npx astro add tailwind
See the Integrations Guide for instructions on installing, importing and configuring Astro integrations.

¥CSS Preprocessors

Astro 支持 CSS 预处理器,例如 SassStylusLessVite

¥Astro supports CSS preprocessors such as Sass, Stylus, and Less through Vite.

¥Sass and SCSS

Terminal window
npm install sass

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

¥Use <style lang="scss"> or <style lang="sass"> in .astro files.

Terminal window
npm install stylus

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

¥Use <style lang="styl"> or <style lang="stylus"> in .astro files.

Terminal window
npm install less

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

¥Use <style lang="less"> in .astro files.

Terminal window
npm install lightningcss

astro.config.mjs 中更新你的 vite 配置:

¥Update your vite configuration in astro.config.mjs:

astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
vite: {
css: {
transformer: "lightningcss",
},
},
})

¥In framework components

你还可以在 JS 框架中使用上述所有 CSS 预处理器!请务必遵循每个框架推荐的模式:

¥You can also use all of the above CSS preprocessors within JS frameworks as well! Be sure to follow the patterns each framework recommends:

  • React / Preact:import Styles from './styles.module.scss';

  • Vue:<style lang="scss">

  • Svelte:<style lang="scss">

Astro 附带了 PostCSS,作为 Vite 的一部分。要为你的项目配置 PostCSS,请在项目根目录中创建一个 postcss.config.cjs 文件。你可以在安装插件后使用 require() 导入插件(例如 npm install autoprefixer)。

¥Astro comes with PostCSS included as part of Vite. To configure PostCSS for your project, create a postcss.config.cjs file in the project root. You can import plugins using require() after installing them (for example npm install autoprefixer).

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

¥Frameworks and Libraries

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

¥.jsx files support both global CSS and CSS Modules. To enable the latter, use the .module.css extension (or .module.scss/.module.sass if using Sass).

src/components/MyReactComponent.jsx
import './global.css'; // include global CSS
import Styles from './styles.module.css'; // Use CSS Modules (must end in `.module.css`, `.module.scss`, or `.module.sass`!)

Astro 中的 Vue 支持与 vue-loader 相同的方法:

¥Vue in Astro supports the same methods as vue-loader does:

Astro 中的 Svelte 也完全符合预期:Svelte 样式文档

¥Svelte in Astro also works exactly as expected: Svelte Styling Docs.

¥Markdown Styling

Markdown 布局组件 可以使用任何 Astro 样式方法,但不同的方法会对你的页面产生不同的样式效果。

¥Any Astro styling methods are available to a Markdown layout component, but different methods will have different styling effects on your page.

你可以通过将 imported stylesheets 添加到封装页面内容的布局来将全局样式应用于 Markdown 内容。还可以在布局组件中使用 <style is:global> 标签 来设置 Markdown 的样式。请注意,添加的任何样式均受 Astro 的级联顺序 约束,你应该仔细检查渲染的页面,以确保你的样式按预期应用。

¥You can apply global styles to your Markdown content by adding imported stylesheets to the layout that wraps your page content. It is also possible to style your Markdown with <style is:global> tags in the layout component. Note that any styles added are subject to Astro’s cascading order, and you should check your rendered page carefully to ensure your styles are being applied as intended.

你还可以添加 CSS 集成 包括 Tailwind。如果你使用 Tailwind,排版插件 对于 Markdown 样式非常有用。

¥You can also add CSS integrations including Tailwind. If you are using Tailwind, the typography plugin can be useful for styling Markdown.

¥Production

¥Bundle control

当 Astro 构建你的站点以进行生产部署时,它会将你的 CSS 缩小并组合成块。网站上的每个页面都有自己的块,此外,多个页面之间共享的 CSS 会进一步拆分成自己的块以供重用。

¥When Astro builds your site for production deployment, it minifies and combines your CSS into chunks. Each page on your site gets its own chunk, and additionally, CSS that is shared between multiple pages is further split off into their own chunks for reuse.

但是,当你有多个页面共享样式时,某些共享块可能会变得非常小。如果全部单独发送,则会导致许多样式表请求并影响网站性能。因此,默认情况下,Astro 只会将 HTML 中大小超过 4kB 的内容链接为 <link rel="stylesheet"> 标签,同时将较小的标签内联到 <style type="text/css"> 中。这种方法在额外请求的数量和页面之间可以缓存的 CSS 量之间提供了平衡。

¥However, when you have several pages sharing styles, some shared chunks can become really small. If all of them were sent separately, it would lead to many stylesheets requests and affect site performance. Therefore, by default Astro will link only those in your HTML above 4kB in size as <link rel="stylesheet"> tags, while inlining smaller ones into <style type="text/css">. This approach provides a balance between the number of additional requests and the volume of CSS that can be cached between pages.

你可以使用 assetsInlineLimit vite 构建选项配置外部链接样式表的大小(以字节为单位)。请注意,此选项也会影响脚本和图片内联。

¥You can configure the size at which stylesheets will be linked externally (in bytes) using the assetsInlineLimit vite build option. Note that this option affects script and image inlining as well.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
build: {
assetsInlineLimit: 1024,
}
};
});

如果你希望所有项目样式保持外部,你可以配置 inlineStylesheets 构建选项。

¥If you would rather all project styles remain external, you can configure the inlineStylesheets build option.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
build: {
inlineStylesheets: 'never'
}
});

你还可以将此选项设置为 'always',这将内联所有样式表。

¥You can also set this option to 'always' which will inline all stylesheets.

¥Advanced

¥?raw CSS Imports

对于高级用例,CSS 可以直接从磁盘读取,无需 Astro 打包或优化。当你需要完全控制某些 CSS 片段并且需要绕过 Astro 的自动 CSS 处理时,这会很有用。

¥For advanced use cases, CSS can be read directly from disk without being bundled or optimized by Astro. This can be useful when you need complete control over some snippet of CSS, and need to bypass Astro’s automatic CSS handling.

不建议大多数用户这样做。

¥This is not recommended for most users.

src/components/RawInlineStyles.astro
---
// Advanced example! Not recommended for most users.
import rawStylesCSS from '../styles/main.css?raw';
---
<style is:inline set:html={rawStylesCSS}></style>

完整详细信息请参见 Vite 的文档

¥See Vite’s docs for full details.

¥?url CSS Imports

对于高级用例,你可以导入项目 src/ 目录内 CSS 文件的直接 URL 引用。当你需要完全控制 CSS 文件在页面上的加载方式时,这会很有用。但是,这将阻止该 CSS 文件与页面 CSS 的其余部分一起优化。

¥For advanced use cases, you can import a direct URL reference for a CSS file inside of your project src/ directory. This can be useful when you need complete control over how a CSS file is loaded on the page. However, this will prevent the optimization of that CSS file with the rest of your page CSS .

不建议大多数用户这样做。相反,请将 CSS 文件放置在 public/ 内以获得一致的 URL 引用。

¥This is not recommended for most users. Instead, place your CSS files inside of public/ to get a consistent URL reference.

src/components/RawStylesUrl.astro
---
// 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 的文档

¥See Vite’s docs for full details.

Astro 中文网 - 粤ICP备13048890号