Bram Mortier
Bram Mortier

Reputation: 63

Passing a class to the generated picture alement Astro <Picture /> component

I'm trying to use the component that astro provides via the astro::assets import. Whenever i try to pass i class to the component it gets rendered on the img tag in the DOM. Is there any way i can pass a class to the generated picture element in the DOM?

This is the component file i'm using:

---
import { Picture } from "astro:assets";

interface Props {
    src: ImageMetadata;
    alt: string;
    sizes: string;
    class?: string;
}

const { src, alt, sizes, class: className, ...props } = Astro.props

---
<Picture
    class:list={["c-image", className]} 
    src={src} 
    alt={alt}
    loading="lazy"
    formats={["webp", "avif"]}
    widths={[640, 768, 1024, 1366, 1600, 1920, src.width]}
    sizes={sizes}
    {...props}
/>

<style scoped lang="scss">
    .c-image {
        width: 100%;
        display: block;

        &--cover {
            object-fit: cover;
            object-position: center;
        }
    }
</style>

DOM result

Upvotes: 1

Views: 177

Answers (1)

Th3S4mur41
Th3S4mur41

Reputation: 2285

I had the same issue, it turns out the class is being passed, not just as one might expect...

So using the component like this: <Picture class="myclass" ...> Does not generate:

<picture class="myclass">
  ...
  <img ...>
</picture>

But rather

<picture>
  ...
  <img class="myclass">
</picture>

So there are two options for styling:

  1. Use :has to apply styles to the targeted picture element instead of the img element.
picture:has(> .c-image) {
  width: 100%;
  display: block;
}
  1. Apply display: contents to the picture element to remove its box and have the img element behave as a direct child
picture {
  display: contents;
}

.c-image {
  width: 100%;
  display: block;
}

Upvotes: 0

Related Questions