把Next.js的Image改成fill後,網址明明能開,頁面卻像少了一張圖片。先別急著改圖片來源或加寬遠端白名單:如果父容器只有寬度、沒有高度,圖片可能已經載入,只是顯示區域的高度為零。這種情況要從版面尺寸查起。
fill讓圖片填滿父元素提供的區域。父容器需要合適的定位,以及由高度、比例或其他版面條件形成的可用尺寸。圖片本身的原始寬高不會自動把這個容器撐高。理解這個關係後,才能分清載入失敗、零高度與裁切方式三種不同問題。
先看父容器有沒有高度
以下範例的父容器只有寬度。雖然已經設定position: relative,仍沒有建立垂直空間。
import Image from 'next/image';
export default function Demo() {
return (
<div style={{ position: 'relative', width: 320 }}>
<Image
src="/demo.svg"
alt="Synthetic demo"
fill
unoptimized
/>
</div>
);
}
這裡的demo.svg是本地自行製作的測試圖,沒有外站來源、使用者上傳內容或任何腳本。unoptimized明確讓它以原檔呈現,以便把測試集中在版面,而不是圖片最佳化服務。這個選擇不是要示範正式網站應全面關閉最佳化,也不需要開啟允許危險SVG的選項。
在這個容器內,fill產生的圖片使用絕對定位,不會像一般文流中的圖片那樣靠自身高度把父元素推開。若父元素沒有其他內容,也沒有高度限制,量到的高度就可能是零。只改width或再寫一次position: relative,都沒有回答「垂直空間從哪裡來」這個問題。
給圖片一個明確的顯示區域
先用固定尺寸做最容易判讀的對照:保留相同圖片與來源,只為父容器加上高度,並選擇保持比例的填入方式。
<div style={{ position: 'relative', width: 320, height: 180 }}>
<Image
src="/demo.svg"
alt="Synthetic demo"
fill
unoptimized
style={{ objectFit: 'contain' }}
/>
</div>
這個範例的容器是320乘180。實際網站可以依設計使用響應式寬度和比例,而不是把所有圖片都固定成這個尺寸;關鍵是容器在顯示時要有可計算的寬高。若高度來自父層版面或網格配置,仍應在瀏覽器確認最終尺寸,不要只看樣式檔裡曾經寫過某個值。
relative是此處方便的定位方式,它保留父元素在一般版面中的位置,讓內部絕對定位的圖片有對應區域。官方文件也列出適用的父元素定位條件。不要看到圖片跑到別處,就直接替整個頁面最外層加定位;先找這張圖片真正要填滿的容器,否則它可能依較遠的祖先元素定位。
載入成功也可能完全看不到
本地範例使用Next.js 16.3.8,透過真實Chromium讀取兩個容器及圖片的尺寸。未指定高度的容器是320乘0,裡面的圖片同樣是320乘0;加上高度後,容器和圖片都成為320乘180。兩份使用的圖檔與來源完全相同。
更值得看的是載入資料:兩張圖片的currentSrc都指向本地demo.svg,complete都是true,naturalWidth也都是320。這組結果表示第一張圖並非沒有取到來源,而是載入後沒有垂直顯示空間。Next.js開發環境另提示fill圖片的高度為零,提醒檢查父容器高度。
不能只用complete判定圖片成功,因為它本身也有其他完成狀態;應一起看實際來源、原始尺寸與資源請求。這個案例的原始寬度與來源相互吻合,再配合零高度盒子,才足以把問題指向版面。若你的站點連原始尺寸都是零,則需要回頭查來源與載入結果,不宜直接套用同一結論。
objectFit控制的是區域內怎麼放圖
容器有尺寸後,才輪到選擇圖片在其中的放法。contain會盡量完整保留圖片比例,比例不同時可能留下空白。cover同樣保持比例,但會填滿區域,因而可能裁掉邊緣。是否能接受裁切,要看圖片內容與設計:產品上的文字或人物頭部,不應因為填滿卡片就被截掉。
本例明確使用contain,實測計算樣式也顯示這個值。沒有設定的對照圖片則顯示預設fill。不要把元件的fill屬性與CSS的object-fit: fill當成同一件事:前者決定圖片填入父元素的定位與尺寸方式,後者描述圖像如何放進既有的圖片盒子。
如果換成cover後只剩圖片中央,先核對容器比例,再考慮合適的object-position。這些設定可以調整保留的位置,卻不能救回原圖根本沒有的內容。對文章封面、商品圖和介面截圖也要分別選擇,不應把同一套裁切規則套到所有圖片。
sizes要對應真的版面寬度
正式頁面若使用響應式fill圖片,官方文件建議提供符合顯示寬度的sizes。它描述不同視窗條件下圖片預期占用的寬度,讓瀏覽器從可用來源選擇適合的資源。這與父容器高度是不同問題;補上sizes不會自動替零高度容器建立空間。
例如桌機卡片占內容區的一部分、手機接近整欄時,應依實際斷點與欄位寬度寫條件,不能只複製別人的百分比。檢查時同時讀容器尺寸和currentSrc,確認版面條件與瀏覽器選到的來源。這份本地SVG案例只有一個直接來源,沒有測試多張最佳化尺寸的選擇或下載量改善。
若父容器的寬度也為零,先查是否被隱藏、所在欄位沒有可用空間,或尺寸依賴尚未成立的祖先元素。當頁面包含摺疊區塊、彈窗或切換分頁時,應在真正顯示圖片的狀態再量一次。某個隱藏區塊中的零尺寸,不等於同一張圖片在展開後仍然失效。
alt與來源安全另行處理
版面修正後仍要填寫適合內容的alt。本例只是幾何測試圖,因此使用明確標示測試性質的文字;正式商品照片、說明截圖與裝飾圖片的替代文字,應依它們在頁面上的用途決定。不要拿檔名或一串搜尋關鍵字代替讀者需要的內容說明。
本地圖檔也不等於所有SVG都安全。這個測試圖由自己建立,只用來隔離版面行為;處理來源不明或使用者可上傳的SVG時,要依專案的內容安全設定與檔案處理流程評估。圖片盒子沒有高度時,擴大遠端來源權限或改動安全設定,都不是這個問題的修正方式。
排查順序可以很具體:先核對真正的圖片請求與來源,再量父容器和圖片的寬高,確認定位參照,最後檢查比例、裁切與響應式來源。每一步都對應一個可觀察的結果。這樣即使畫面仍然空白,也能把原因縮小到需要調整的地方,避免反覆換圖卻沒有改到版面條件。

評論0