0

I have been trying to import frontmatter into css with Astro and cannot figure out how to put it into the css. I need it to work this way because I am trying to be able to update a background image for each item through the markdown file.

Card.astro

---
const allvideos = await Astro.glob("../content/videos/*.md");
---

{
  allvideos.map((video) => (
    <div class="mb-4 col-md-6">
      <div class="h-100 p-5 text-light rounded-3 background">
        <h2>{video.frontmatter.name}</h2>
        <p>{video.frontmatter.desc}</p>
        <a class="btn btn-outline-light btn-lg" type="button" href={video.frontmatter.link} target="_blank">Watch Now</a>
      </div>
    </div>
  ))
}

<style>
  .background {
    min-height: 100%;
    background: linear-gradient(0deg, rgb(0, 0, 0, 0.8), rgb(24, 24, 24, 0.8)),
      url(../images/{video.frontmatter.image});
    background-size: cover;
    background-position: center;
  }
</style>

Markdown File

---
name: "Name"
desc: "Description"
link: link
image: imagename.webp
---
Nathanael
  • 1
  • 1

1 Answers1

1

To pass variables from frontmatter to CSS you can use Astro’s define-vars directive.

In a simple example:

---
const image = "image.png";
---

<div class="background" />

<style define:vars={{ bgImage: `url(../images/${image})` }}>
  .background {
    background: var(--bgImage);
  }
</style>

Because you want to set a different image for each item in the loop, to use define:vars you would need to create a component you use inside the loop:

---
// Card.astro

interface Props {
  name: string;
  desc: string;
  link: string;
  image: string;
}

const { image, name, desc, link } = Astro.props;
---

<div class="mb-4 col-md-6">
  <div class="h-100 p-5 text-light rounded-3 background">
    <h2>{name}</h2>
    <p>{desc}</p>
    <a class="btn btn-outline-light btn-lg" type="button" href={link} target="_blank">Watch Now</a>
  </div>
</div>

<style define:vars={{ bgImage: `url(../images/${image})` }}>
  .background {
    min-height: 100%;
    background:
      linear-gradient(0deg, rgb(0, 0, 0, 0.8),
      rgb(24, 24, 24, 0.8)),
      var(--bgImage);
    background-size: cover;
    background-position: center;
  }
</style>

Then use the component in the loop in your template:

---
import Card from '../Card.astro';
const allvideos = await Astro.glob("../content/videos/*.md");
---

{
  allvideos.map((video) => <Card {...video.frontmatter} />)
}

N.B. The approach you’re using to create the image URLs may not work depending on how you’re storing the images in your project. Check out Astro’s image docs for details about resolving and importing images.

swithinbank
  • 1,127
  • 1
  • 6
  • 15