vikky
vikky

Reputation: 321

Next Image not taking class properties

I am using Next.js and next/image to display images, but the CSS is not working inside it. The image is in SVG format and I have placed it in the public folder. I am using Tailwind CSS along with this.

<Image
  className="mt-3"
  data-testid="close-icon"
  src="/CloseIcon.svg"
  alt="Close Nav Bar"
  height="24"
  width="24"
/>

I am not sure why it is not working and it is not being reflected in the browser. Any help will be greatly appreciated!

Upvotes: 26

Views: 50694

Answers (5)

Dan
Dan

Reputation: 31

If looking for quick and easy option, without the use of classes then you can style it inline. Of course this has scalability type questions but if its a one off task then this should work:

   <div style={{ marginTop: '3px' }}><Image
    data-testid="close-icon"
    src="/CloseIcon.svg"
    alt="Close Nav Bar"
    height="24"
    width="24"
/></div>

Upvotes: 0

juliomalves
juliomalves

Reputation: 50278

Before Next.js 12.2

Styling the next/image component's margins this way doesn't work in older Next.js versions. See relevant GitHub discussion for more details.

Internally to the next/image component, the <img> element and the elements that wrap it have inline styles that override certain values passed through className.

As a workaround, you can add a wrapper element and apply the margin styling to it instead.

<div className="mt-3">
    <Image
        data-testid="close-icon"
        src="/CloseIcon.svg"
        alt="Close Nav Bar"
        height="24"
        width="24"
    />
</div>

From Next.js 12.2

You can use the next/future/image component instead. This new component renders a single <img> element without any additional wrappers by default, and is no longer constrained by the wrapper's styles override.

You can enable next/future/image in next.config.js.

module.exports = {
    experimental: {
        images: {
            allowFutureImage: true
        }
    }
}

From Next.js 13

The next/future/image component has been converted to next/image. Like next/future/image, this component renders a single <img> element and can be styled directly with className/styles.

Upvotes: 41

Abdulsalam
Abdulsalam

Reputation: 293

Wrapping the image component in a div helps solve the issue for me. I can apply the class name to the div and everything works as it should.

Upvotes: -1

francis
francis

Reputation: 4505

Try this:

<div style='width:104px;height:104px;position:relative;'>
  <Image
    alt='Mountains'
    src='/mountains.jpg'
    layout='fill'
    objectFit='contain'
  />
</div>

More on objectFit Here

Upvotes: 5

Andrew Kruglik
Andrew Kruglik

Reputation: 302

Juliomalves's answer is right, but I would prefer:

<div className="mt-3" height="24" width="24">
    <Image
        data-testid="close-icon"
        src="/CloseIcon.svg"
        alt="Close Nav Bar"
        layout="fill"
    />
</div>

You also can use a little cheat:

import {motion} from "framer-motion";

    <motion.img 
      className="mt-3"
      data-testid="close-icon"
      src="/CloseIcon.svg"
      alt="Close Nav Bar"
      height="24"
      width="24">

Upvotes: 12

Related Questions