#How to create CSS string from JS at build time

4 messages · Page 1 of 1 (latest)

timid agate
#

I need to dynamically generate some CSS at build time from JS including the CSS selectors so I don't think define:vars will work. Basically I want to create:

html[data-theme="some-theme"] { ... }
html[data-theme="another-theme"] { ... }
/* more themes if necessary... */

where "some-theme" and "another-theme" are derived from a variable length list in the site config file. I want to put this generated CSS in a global style tag. Is this even possible?

mint emberBOT
#

Hi @timid agate. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Astro does not provide a built-in way to generate CSS strings from JavaScript at build time and inject them directly into a global <style> tag, especially when you need to generate selectors dynamically (e.g., for themes) and not just variable values. The define:vars directive only allows you to pass variables into CSS, not generate selectors or rules themselves, and it is not supported for dynamic tags or for generating arbitrary CSS selectors from JS arrays or objects define:vars reference Dynamic Tags.

However, you can consider these approaches, based on the documentation:

  1. Generate a CSS file at build time (outside Astro) and import it globally:

    • Write a script (Node.js or similar) that reads your config and generates a CSS file (e.g., themes.css) with the desired selectors.
    • Place this file in your src/styles/ directory.
    • Import it in your Astro project using a standard import in your frontmatter:
      import '../styles/themes.css';
      
    • This will apply the styles globally Import CSS Add a global stylesheet.
  2. Advanced: Inline CSS using is:inline or set:html (not recommended for most users):

    • You could technically import a raw CSS string and inject it into a <style is:inline set:html={rawCSS}> tag, but this is considered advanced and not recommended for most users. You would need to generate the CSS string yourself and import it using the ?raw suffix Advanced CSS imports.
#

Example:

---
// Advanced: Not recommended for most users
import rawThemesCSS from '../styles/themes.css?raw';
---
<style is:inline set:html={rawThemesCSS}></style>

Summary:
Astro does not natively support generating CSS selectors from JS at build time within the .astro file itself. The recommended approach is to generate your CSS file outside of Astro (e.g., with a Node.js script), then import it globally into your project Import CSS. If you need to inline the CSS, you can use the advanced ?raw import pattern, but this is not the standard workflow and comes with caveats.

If you need more details on how to set up the external script or further integrate it into your build process, let me know!

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: