Skip to content

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:

package/src/pages/index.astro
---
import "my-theme:styles";
---

When styling a theme, always use virtual imports so that theme users can override the styles:

package/src/pages/index.astro
---
// DO use virtual imports
import "my-theme:styles";
// DO NOT use relative imports
import "../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
package/src/pages/index.astro
---
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',
],
},
})
package/src/pages/index.astro
---
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:

package/src/pages/index.astro
---
// DO use virtual imports
import "my-theme:styles";
// DO NOT use relative imports
import "../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.

package/src/pages/index.astro
---
import { Layout } from 'my-theme:layout'
import { Component } from 'my-theme:components'
// Place style import below all other imports
import "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:

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%;" />