Styling a theme
Theme integrations can be styled just like any other Astro project, but there are a few conventions that theme authors should follow to create themes that are customizable and compatible with each other.
Virtual modules
Astro Theme Provider uses virtual modules for styling, enabling complete customization for theme users through overrides:
---import "my-theme:styles";---When styling a theme, always use virtual imports so that theme users can override the styles:
---// DO use virtual importsimport "my-theme:styles";// DO NOT use relative importsimport "../styles/global.css";---Default style module
By default, all styles inside the src/styles directory will be combined into a virtual module:
Directorypackage
Directorysrc
Directorystyles
- reset.css
- styles.css
- utilities.css
---import 'my-theme:styles';---The default style module can be overridden using the imports option.
This may be useful for cases like importing fonts or controlling the order of styles inside the module. For example:
export default defineTheme({ name: 'my-theme', imports: { styles: [ '@fontsource-variable/inter' './src/styles/reset.css', './src/styles/global.css', './src/styles/utilities.css', ], },})Custom style modules
Themes have access to a default style module, but authors can create as many style modules as they want using the imports option.
export default defineTheme({ name: 'my-theme', imports: { // Use a string to glob files inside the 'src' folder 'styles/blog': 'styles/blog/**/*.{css,scss}',
// Use an array to manually define imports and control order 'styles/gallery': [ '@fontsource-variable/inter', './src/styles/gallery/reset.css', './src/styles/gallery/global.css', './src/styles/gallery/utilities.css', ], },})---import 'my-theme:styles/blog';import 'my-theme:styles/gallery';---Creating overridable styles
All themes should be authored with style systems that are easy to customize, compatible with user projects, and compatible with other theme integrations.
Importing styles
Styles should always be imported using virtual modules:
---// DO use virtual importsimport "my-theme:styles";// DO NOT use relative importsimport "../styles/global.css";---Styles will apply as a cascade, in the order they are imported. Always place virtual style imports below all other imports to avoid issues with theme users overriding styles.
---import { Layout } from 'my-theme:layout'import { Component } from 'my-theme:components'// Place style import below all other importsimport "my-theme:styles";---CSS Layers
All styles inside a theme should be authored using CSS layers.
@layer my-theme { :root { --my-color-bg: #222222; }
body { background-color: var(--my-color-bg); }}CSS layers allows users to have full control over the order that styles cascade. For example:
@layer blog-theme, my-theme, docs-theme, user-overrides;Read more about CSS layers here:
CSS variables
Theme authors should make use of CSS variables to enable style themes that are easy to customize and override. For example:
:root { --my-color-fg: #fefefe; --my-color-bg: #222222;}
/* DO use css variables */body { background-color: var(--my-color-bg); color: var(--my-color-fg);}
/* DO NOT hardcode values */body { background-color: #222222; color: #fefefe;}CSS variables should always include a unique prefix to avoid collisions with existing styles.
Read more about creating style systems with CSS variables here:
- Building Design Systems with CSS Variables - Nicolas Pardo
- Building your own Modern CSS Design System - Rocky Kev
- How to create better themes with CSS variables - Michelle Barker
Class names
Theme authors should include classes on elements, even if the element is not being styled. Classes allow users to target elements inside a theme with style changes. For example:
<!-- DO use unique descriptive class names --><article class="my-card"> <h1 class="my-card__title"></h1> <img class="my-card__image"/> <p class="my-card__description"></p></article>
<!-- DO NOT use broad generic class names --><article class="card"> <h1></h1> <img/> <p></p></article>Class names should always include a unique prefix to prevent collisions with existing styles.
Read more about choosing names for classes here:
Style patterns to avoid
Style attributes
Avoid using style attributes as they have a high specificity, making them hard for users override.
<img src="" alt="" style="height:auto;width:100%;" />