Search code examples
csscomponentsmarkdownastrojs

How can I force Astro to render my markdown with scoped classes within a component?


I have an Astro component in which I'm rendering markdown to html (with @astropub/md), and then trying to target the rendered markdown with scoped CSS within the component.

However, the css scoping is expecting classes that are not being rendered by @astropub/md.

Ex:

---
import { markdown } from "@astropub/md";
---

<p>this text is not bold, <strong>but this is</strong>.</p>
{markdown("this text is not bold, **but this is**.")}
<style>
   strong {
      color: red;
   }
</style>

This will effectively render like so:

<style type="text/css">
  strong:where(.astro-UW5KDBXL){
    color:red
  }
</style>
<p class="astro-UW5KDBXL">
  this text is not bold, <strong class="astro-UW5KDBXL">but this is</strong>.
</p>
<p>
  this text is not bold, <strong>but this is</strong>.
</p>

The example that is rendered from markdown is missing the classes that the scoped style definitions are using to color the text.

I've added the markdown package to my astro.config.mjs integrations, but that doesn't seem to change how it renders the markdown.

I can use <style is:inline or <style is:global>, but then I lose the scoped nature, and I feel like that would defeat one of the advantages of Astro's 'island' structure.

So how do I force astropub/md to render the scoped classes?


Solution

  • You can use the :global CSS selector to apply the styles to child elements of that component.

    ---
    import { markdown } from "@astropub/md";
    ---
    
    <p>this text is not bold, <strong>but this is</strong>.</p>
    {markdown("this text is not bold, **but this is**.")}
    <style>
       :global(strong) {
          color: red;
       }
    </style>