26

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!

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
vikky
  • 321
  • 1
  • 4
  • 8

4 Answers4

39

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.

juliomalves
  • 42,130
  • 20
  • 150
  • 146
11

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">
Andrew Kruglik
  • 182
  • 1
  • 11
  • 1
    You might want to put width and height in style since div doesn't take width and height directly `
    `
    – Xitang May 08 '22 at 07:15
5

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

francis
  • 3,852
  • 1
  • 28
  • 30
-1

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.

Abdulsalam
  • 275
  • 4
  • 6