Styles & CSS
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
Section titled Styling in AstroStyling 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.
Scoped Styles
Section titled Scoped StylesAstro <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.
This CSS:
Compiles to this:
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.
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.
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
Section titled Global StylesWhile 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.
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.
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
Section titled Combining classes with class:listIf you need to combine classes on an element dynamically, you can use the class:list
utility attribute in .astro
files.
📚 See our directives reference page to learn more about class:list
.
CSS Variables
Section titled CSS Variablesastro@0.21.0
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.
📚 See our directives reference page to learn more about define:vars
.
Passing a class
to a child component
Section titled Passing a class to a child componentIn Astro, HTML attributes like class
do not automatically pass through to child components.
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.
This pattern lets you style child components directly. Astro will pass the parent’s scoped class name (e.g. astro-HHNQFKH6
) through the class
prop automatically, including the child in its parent’s scope.
Inline styles
Section titled Inline stylesYou can style HTML elements inline using the style
attribute. This can be a CSS string or an object of CSS properties:
External Styles
Section titled External StylesThere 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
Section titled Import a local stylesheetYou 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.
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
Section titled Import a stylesheet from an npm packageYou 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:
If your package does not suggest using a file extension (i.e. package-name/styles
), you’ll need to update your Astro config first!
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:
Now, you are free to import package-name/normalize
. This will be bundled and optimized by Astro like any other local stylesheet.
Load a static stylesheet via “link” tags
Section titled Load a static stylesheet via “link” tagsYou 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.
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
Section titled Cascading OrderAstro 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.
When conflicting CSS rules apply to the same element, browsers first use specificity and then order of appearance to determine which value to show.
If one rule is more specific than another, no matter where the CSS rule appears, its value will take precedence:
If two rules have the same specificity, then the order of appearance is evaluated, and the last rule’s value will take precedence:
Astro CSS rules are evaluated in this order of appearance:
<link>
tags in the head (lowest precedence)- imported styles
- scoped styles (highest precedence)
Scoped Styles
Section titled Scoped StylesUsing 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:
If you make the imported style more specific, it will have higher precedence over the scoped style:
Import Order
Section titled Import OrderWhen 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:
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:
Link Tags
Section titled Link TagsStyle 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:
CSS Integrations
Section titled CSS IntegrationsAstro comes with support for adding popular CSS libraries, tools, and frameworks to your project like Tailwind and more!
Tailwind
Section titled TailwindTo use Tailwind in your project, install the official Astro Tailwind integration using the astro add
command for your package manager:
📚 See the Integrations Guide for instructions on installing, importing and configuring Astro integrations.
CSS Preprocessors
Section titled CSS PreprocessorsAstro supports CSS preprocessors such as Sass, Stylus, and Less through Vite.
Sass and SCSS
Section titled Sass and SCSSUse <style lang="scss">
or <style lang="sass">
in .astro
files
Stylus
Section titled StylusUse <style lang="styl">
or <style lang="stylus">
in .astro
files
Use <style lang="less">
in .astro
files.
In framework components
Section titled In framework componentsYou 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">
PostCSS
Section titled PostCSSAstro 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
).
Frameworks and Libraries
Section titled Frameworks and Libraries📘 React / Preact
Section titled 📘 React / Preact.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).
📗 Vue
Section titled 📗 VueVue in Astro supports the same methods as vue-loader
does:
📕 Svelte
Section titled 📕 SvelteSvelte in Astro also works exactly as expected: Svelte Styling Docs.
Markdown Styling
Section titled Markdown StylingAny Astro styling methods are available to a Markdown layout component.
You can apply global styles to your Markdown content by adding <style>
tags and imported stylesheets to the layout that wraps your page content. You can also add CSS integrations including Tailwind.
If you are using Tailwind, the typography plugin can be useful for styling Markdown.
Production
Section titled ProductionBundle control
Section titled Bundle controlWhen Astro builds your site for production deployment it combines your CSS into chunks. Each page on your site is its own chunk, and additionally, CSS that is shared between multiple pages is further split off into their own chunks for reuse.
In each of your HTML files there will be <link rel="stylesheet">
tags added, one for each of the chunks that the pages needs.
Sites with a large number of pages and many different shared styles can lead to many stylesheet requests and affect site performance. You can configure the inlineStylesheets
option to reduce the number of these requests by putting (minimized) stylesheets into a <style>
tag rather than request them externally.
The 'auto'
option will inline only the stylesheets that are below the vite.build.assetsInlineLimit
threshold, reducing the number of requests for smaller sheets. Larger stylesheets, such as global ones used by all pages, will still be fetched externally and cached. This option provides a balance between the number of stylesheets loaded and the styles that can be cached between pages.
You can also set this option to 'always'
which will inline all stylesheets.
Advanced
Section titled Advanced?raw
CSS Imports
Section titled ?raw CSS ImportsFor 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.
See Vite’s docs for full details.
?url
CSS Imports
Section titled ?url CSS ImportsFor 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 .
This is not recommended for most users. Instead, place your CSS files inside of public/
to get a consistent URL reference.
See Vite’s docs for full details.