【TailwindCSS＋React+Next.js】Next.jsでの画像の表示とアスペクト比の保ち方

# はじめに

Next.jsのnext/imageを使用した静的ファイルの表示方法と、画像を表示させたさせた際に、画像の比率を維持することに困ったため、その方法を簡単にまとめました。

# 環境

- OS：macOS Big Sur version 11.6
- Next.js：11.0.2
- Tailwind CSS：2.2.15
- React：17.0.2


# next/imageについて

##メリット
- ブラウザに合わせて自動で最適化された状態でレンダリングされる。
- 画像の表示を高速化できる。

##最低限必要なプロパティ

- src：静的ファイルのパス
- width：幅
- height：高さ

【注意点】
- 静的ファイルはpublicフォルダに入れる(私はpublicの中にimagesフォルダを作成し格納)
- [Next.js公式](https://nextjs.org/docs/basic-features/image-optimization)より、Next.jsはビルド中にリモートファイルにアクセスできないため"width"や"height"の指定が必要である。

（画像が全然表示されないと思ったら、TailwindCSSのClasNameで画像サイズを指定して満足していたからでした。Imageにwidthとheightのプロパティを追加したら無事表示されました！）


##記述方法

画像を表示させるためのCardというコンポーネントを定義し、Mainのコンポーネントで3つインポートする。

```javascript:Card.jsx
//'next/image'のコンポーネントをインポートする
import Image from 'next/image'

const Card = (props) => {
  return (
    <Image
      src={props.src}
      //画像のパスをsrcで受け取る
      alt={props.alt}
      //altの文言をaltで受け取る
      width={180}
      height={180}
      className=""
    />
  )
};

export default Card;
```

```javascript:Main.jsx
import Card from './Card'


const Main = (props) => {
    return (
        <div className="grid grid-cols-3 auto-cols-max items-center mx-36 px-20">
          <Card 
            //Imageの{props.srcに'/images/about-1.pngを受け渡し'}
            src={'/images/about-1.png'}
            //Imageの{props.altに'about画像１'を受け渡し}
            alt={'about画像1'}
          />
          <Card 
            src={'/images/about-2.png'}
            alt={'about画像2'}
          />
          <Card 
            src={'/images/about-3.png'}
            alt={'about画像3'}
          />
        </div>
    )
};

export default Main;
```

→　３種類の画像が３つ並ぶ。




#アスペクト比の保ち方

##指定なし(ゆがむ)

```javascript:Card.jsx

import Image from 'next/image'

const Card = (props) => {
    return(
        <div className="h-full p-3">
            <Image              
              src={props.src} 
              alt={props.alt}　
              width={180} 
              height={180}
              className="h-2/5 m-auto" 
             />
            //指定なし
            <h3 className="">{props.title}</h3>
            <p className="">{props.text}</p>
        </div>
    )
};

export default Card;
```

![固定なし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1338748/c63bd7d9-17ed-b563-8d82-4c72c2bfa6e3.png)

## TailwindCSSで指定（ゆがまない）

.object-containを指定することで、要素のコンテンツのサイズを変更し、コンテナ内に含まれたままにします。
参考：[TailwindCSS公式](https://tailwindcss.jp/docs/object-fit)

```javascript:Card.jsx

import Image from 'next/image'

const Card = (props) => {
    return(
        <div className="h-full p-3">
            <Image              
              src={props.src} 
              alt={props.alt}　
              width={180} 
              height={180}
              className="object-contain h-2/5 m-auto" 
             />
            //TailwindCSSのClasNameにobject-contain
            <h3 className="">{props.title}</h3>
            <p className="">{props.text}</p>
        </div>
    )
};

export default Card;
```


![TailwindCSS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1338748/b4b3a38a-4bf1-b20f-819f-0c100e979f49.png)


## Next.jsで指定（ゆがまない）

Imageコンポーネントの'objectFit'プロパティに'contain'を指定すると、画像のアス比を保ちながら、縦か横にできるだけ大きく表示してくれる。

```javascript:Card.jsx

import Image from 'next/image'

const Card = (props) => {
    return(
        <div className="h-full p-3">
            <Image 
              src={props.src} 
              alt={props.alt}　
              width={180} 
              height={180}  
              objectFit="contain"
              className="h-2/5 m-auto" 
             />
            //ImageにobjectFit="contain"
            <h3 className="">{props.title}</h3>
            <p className="">{props.text}</p>
        </div>
    )
};

export default Card;
```
![Next_js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1338748/68c7c648-7b88-0277-e598-55cb4339313a.png)

参考：[next/imageのドキュメント](https://nextjs.org/docs/api-reference/next/image#layout)


#おわり

私にCSSの知識が足りず、画像がゆがんでしまうのを食い止めるのに苦戦しました。
修正方法を調べていく上で、アスペクト比という言葉も知りました。

同じことで困っている人の役に立てたら嬉しいです！