Add class to PrismicImage - Svelte

How to add classes to PrismicImage?

Hi all! :slight_smile:
I am trying to follow the Prismic+SveltKit portfolio tutorial to understand what the "good practices" are when using Prismic.

At one point during the tutorial we can see the presenter add classes to the PrismicImage field like in the image below, but I can't seem to be able to replicate it.

image

Is there a way for me to directly style the generated by PrismicImage? Without the ability to do so, it's making responsiveness a little bit complicated, and I don't really see the advantages of using PrismicImage rather than just fetching src and alt text from the object.

I know I probably have misunderstood something. How can I style prismic objects like PrismicImage, PrismicRichText etc?

Yes, it's definitely possible to style the images generated by `PrismicImage. Could you share your full code, including your CSS? That way, I can take a closer look and help you resolve the issue directly.


Alternative Solution: Using srcset and sizes

Another good practice, especially for responsiveness, is using the widths and sizes attributes with PrismicImage to serve different image resolutions depending on screen size. This takes advantage of the built-in optimizations from Prismic.

Here's how:

<script>
  import { PrismicImage } from '@prismicio/svelte';
</script>

<PrismicImage 
  field={yourPrismicImageField} 
  widths="[320, 640, 1280]"   /* Image sizes that will be generated */
  sizes="(max-width: 640px) 100vw, (max-width: 1280px) 50vw, 33vw" /* How the image scales based on viewport size */
  class="custom-image"
/>

<style>
  .custom-image {
    border-radius: 8px;  /* Apply a border radius directly */
  }

  img {
    max-width: 100%;  /* Makes the image responsive */
    height: auto;     /* Maintain the aspect ratio */
  }
</style>

Explanation:

  1. widths: This defines which widths will be used to generate optimized versions of the image from Prismic (e.g., 320px, 640px, and 1280px wide images).

  2. sizes: This controls how the image should be displayed at different viewport widths:

    • 100vw for screens below 640px (the image takes up the full width of the viewport).
    • 50vw for screens between 640px and 1280px.
    • 33vw for larger screens.

This ensures the correct image is loaded for the user’s screen size, improving performance and responsiveness.


PrismicImage Advantages:

Using PrismicImage from the Prismic API offers several advantages over manually fetching the src and alt text from the image field. Here are the main benefits:

Feature PrismicImage Manually Fetching src & alt
Image Optimization Automatic via Prismic CDN Must be handled manually
Responsive Images Easily handles srcset and sizes Must be implemented manually
Lazy Loading Built-in Must be added manually
CDN Prismic CDN integration Requires separate setup
Code Simplicity Clean, declarative code More verbose, manual setup
Future-Proofing Automatically updates with Prismic Requires manual updates

In conclusion, while it’s possible to manually fetch the src and alt text and handle everything yourself, using PrismicImage provides built-in optimizations, responsiveness, and easier management, which greatly improves performance, maintainability, and code simplicity.

1 Like

Thank you @Phil for this response!
Unfortunately that doesn't seem to work for me. Here's an example of what I get using a component implementing PrismicImage using the code you suggested:

image

As you can see here, the corners of the image are not rounded by the .custom-image class. The warnings I get are about the class and the tag not being seen as used within the code.

Can you show me the exact errors? As much information as possible is always helpful.

You can see in our sample project that applying Tailwind class works perfectly:

Thanks Phil.

Here's what I get. Those are not errors per-se, but alerts from VSCode.
image

Note that I am not using Tailwind,
This issue is happening (or rather not happening since I just cannot style the element) when I try to apply a class from the CSS part of the .svelte component.
Styling the image tag in my global CSS file I am loading on +layout.svelte is working, though.

I understand it's just tailwind classes are just CSS classes, so they should act the same.

Can you provide me with a GitHub link to your project so I can test it?

Thanks

Sure, here you go

In your example, the CSS class custom-image is applied to the PrismicImage component, but Svelte's scoped styles might not apply directly to the content inside the PrismicImage component. This is because third-party components like PrismicImage often render their own markup, and the styles from your component don't automatically cascade into the internal elements.

To resolve this, you can try one of the following approaches:

1. Use a global style override (via :global)

You can force the styles to apply globally, which will work regardless of how the third-party component renders its internal elements:

<style>
	:global(.custom-image) {
		max-width: 300px;
	}
</style>

This will make sure the custom-image class applies to any element globally, including the ones rendered by PrismicImage.

2. Target internal elements using ::deep

If you want to apply scoped styles and target elements within the PrismicImage, you can use the ::deep (or /deep/ in some versions) combinator:

<style>
	::deep(.custom-image) {
		max-width: 300px;
	}
</style>

This allows you to target elements rendered inside components like PrismicImage.

Either of these solutions should help your styles take effect. Let me know if you need more help debugging!

1 Like

Thanks for checking it out, @Phil .
::deep doesn't work with Svelte, so all in all the only way to style Prismic components is to use global CSS, which kind of defeats the purpose of Svelte's component scope.

The Prismic documentation is not very clear on this subject, might I suggest adding this notion in the SvelteKit + Prismic FAQ?

You're welcome Max :slight_smile:

I don't believe this is a Prismic issue, though. It's a Svelte styling question, so we won't add it to the docs. However, this thread should help anyone in a similar situation.

One way to style a component with scope could be like this:

<script>
  import Component from "./Component.svelte";
</script>

<div>
	<div class="parent">
	  <Component class="childClass" />
  </div>
	<Component class="childClass" />
</div>

<style>
  .parent :global(.childClass) {
    color: red;
  }
</style>

You can test that here:

You'll see that while it's set global, it's only targeted to children in the parent class.

This should allow the behaviour your searching :slight_smile:

1 Like