📷
【Next.js v13】Imageコンポーネントを使ってレスポンシブ対応する
こんにちは、フロントエンドエンジニアのShumpei(@seventhseven)です。
個人サイトで使っているNext.jsのバージョンをうっかり13に上げてしまいました。
それによってnext/image
も仕様が変わり、その結果モバイル表示時のレイアウトが崩れてしまいました。
今回はnext/image
画像のレスポンシブ対応を修正した話になります。
バージョン
- Next.js: 13.1.1
- React.js: 18.2.0
結論:Imageコンポーネントのラッパーを作った
ページのある部分で使っているImageコンポーネントが対象だったため、
汎用的なCSSを付与した薄いラッパーを用意し、それを使用する方式を取りました。
import Image from "next/image";
export default function MyImageWrapper({ src, alt }) {
return (
<div className="relative">
<div className="imageContainer">
<Image src={src} alt={alt} fill responsive className="imageItem" />
</div>
</div>
);
}
Imageコンポーネントにはfill
とresponsive
属性を追加しました。
fill属性がついているため、Imageコンポーネント自身にはwidthとheightを付与しなくてもエラーになりません。
(responsive属性も同時につけるのは正しいのか要確認)
CSSはそれぞれのDOMにつけています。
- 一番外側のdiv ...
relative
クラス - 真ん中のdiv ...
imageContainer
クラス - Imageコンポーネント ...
imageItem
クラス
.relative {
position: relative;
}
.imageContainer {
height: 100%;
}
.imageItem {
object-fit: contain;
position: relative !important;
}
Imageコンポーネントは描画時に自動的にposition: absolute
がつけられるため、
position: relative !important
で打ち消します。
打ち消さないと画像分の高さが確保できません。
importantをつけるのはなかなか憚られますが。。。
また、使う時はさらに外側に横幅を指定したDOMを用意します。
この横幅分だけ画像が表示されます。
まとめ
まだまだ自分はnext/image
の理解が浅く、このような形を取りました。
個人サイトなので、色々と試している途中です。
レスポンシブは必須な要素なので、よりよい方法を探っていきたいと思います。
Discussion
16:9の画像限定となりますが、親要素に「aspect-video」を指定した上で子要素(Image)に「object-cover」とfillをつけるとシンプルに収まるので多用しています。
ありがとうございます、勉強になります!