CSS 小技巧:如何將 img 轉換成 background-image
一、img vs background-image
大部分注重內容的圖片(比如商品展示、文章配圖)都推薦直接使用img標簽,好處有很多,比如
- img支持天然懶加載,設置loading="lazy"
<img src='xxx.png' loading="lazy">- img支持各種JS監(jiān)聽,比如加載成功、加載失敗
<img src='xxx.png' onload="" onerror="">- img支持自定義解碼,同步還是異步
<img src='xxx.png' decoding="sync">- img對SEO更加優(yōu)化,對可訪問性更好
<img src='xxx.png' alt="頭像">但是,除了上面這些,在視覺表現(xiàn)上,圖片靈活性就不如背景圖片了。
比如img不支持重復平鋪、不支持圖片疊加等等,也不像普通標簽還可以使用偽元素。
這樣就導致很多時候,比如要在img外面嵌套一層容器再額外處理,還是有些不便的,特別是在HTML不方便修改的情況下。
那么,有沒有什么辦法,可以將img轉換成background-image呢? 也就是使用img標簽,但是卻可以使用背景圖的諸多特性。
image-20250822194214247
二、img 的層級
img是一個可替換標簽,意思就是這個標簽的渲染內容是由外部決定的。
這樣就導致img和一般標簽有些不同,比如沒有偽元素,而且「資源的層級是高于一些裝飾性屬性的」,例如背景、內陰影等
image-20250823103620523
比如,我們給一個img標簽添加一個背景。
<img src="xxx.png" style="background:red">效果如下:
image-20250823103843453
沒有看到任何紅色背景,說明圖片的層級是高于背景的。
如果我們換一個帶透明像素的圖片,就能看到背景了。
image-20250823104022461
所以,下面的問題就是,如何把img本身的圖片給隱藏起來?
三、如何隱藏 img 資源?
當然這里說的隱藏并不是直接隱藏整個img標簽,比如:
img {
opacity: 0 /*????*/
}這樣的話,整個標簽都看不見了,背景也看不見了,也就失去了轉換的意義。
那還有什么辦法可以隱藏呢?這里有兩種方式。
1. 通過content替換內容
在之前,可以從可替換標簽入手,通過content屬性可以改變可替換元素的內容,就像這樣。
img {
content: url(xx.png)
}我們給img標簽一個透明的圖片內容,就可以替換img原本的顯示了,這里可以用1*1像素的透明gif。
img {
content: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}但是,這樣設置以后,圖片完全不可見了。這樣因為,此時的img已經(jīng)被渲染成1*1像素了。
image-20250823111419050
所以在用這種方式時,必須手動指定寬高。
img {
content: url(xxx.png);
width: 300px;
height: 300px;
}為了方便觀察,我們加上邊框。
image-20250823111006597
這樣原始的img鏈接已經(jīng)被隱藏了。
2. 通過object-position偏移
上面的方式比較硬核,還可以設置一張錯誤的圖片,讓圖片展示直接出錯,這樣還能使用偽元素。
不過,有個小缺陷是,必須要手動指定圖片寬高,可能存在一定的限制。
下面介紹另一個方式,那就是通過object-positon收到改變圖片的顯示位置。比如:
img {
object-position: 100px;
}效果如下:
image-20250823112432629
我們只需要給個足夠大的值,圖片就完全移出標簽外了。
img {
object-position: 100vw; /**足夠大的偏移/
}這樣也能隱藏圖片的展示,而且也不影響img原本尺寸。
image-20250823111006597
注意,這里不能用object-position: 100%來實現(xiàn),和背景位置比較像,100%表示居右了,并不是向右偏移自身的100%。
四、如何通過背景圖片顯示
再回到img標簽本身,有辦法直接通過src屬性直接顯示為背景圖片嗎?
<img src="xxx.png">在之前這篇文章:原子化的未來?了解一下全面進化的CSS attr函數(shù) 有提到attr的新特性。
但是,出于安全考慮,并不能直接顯示背景圖片。
img{
background: url(attr(src));
}其實呢,還可以用image-set來直接渲染字符串格式的資源,寫法如下。
img {
background: image-set(attr(src));
}這個技巧是在張鑫旭的這篇文章中學到的:https://www.zhangxinxu.com/wordpress/2025/05/css-attr-function/
效果如下:
image-20250823115359509
背景尺寸有些不對,我們調整一下。
img {
background: image-set(attr(src)) 0 0/100%;
}這樣就通過背景完美替換了圖片。
image-20250823115545747
不過這個需要用過attr的新特性,要求兼容性 chrome 133+。
更常見的做法是通過自定義屬性來實現(xiàn)。
<img src="xxx.png" style="--bg: url(xxx.png)">然后直接使用這個變量。
img {
background: var(--bg) 0 0/100%;
}五、轉換成背景圖片后的好處
費了一番功夫轉換成了背景圖片,有哪些好處呢?下面舉幾個例子。
1. 圖片內邊框
通常我們使用border實現(xiàn)的邊框都是外邊框,無法直接覆蓋在圖片上,有時候需要一種半透明邊框來強化圖片的輪廓,比如下面的書封。
img
這時,我們可以通過內陰影來實現(xiàn)這樣的效果(內陰影的層級高于背景)。
img {
background: image-set(attr(src)) 0 0/100%;
border-radius: 8px;
box-shadow: inset 0 0 0 2px rgba(0,0,0,.1)
}效果如下:
image-20250823122050743
2. 圖片高光或者水印
有時候書封還需要高光或者水印,這樣會更有質感一些,就像這樣。
image-20250823123002130
這時,我們可以直接給圖片疊加一層高光素材就行了。
img {
background: url("https://imgservices-1252317822.image.myqcloud.com/coco/s03272025/e21047d7.v7q5ko.png") 0 0/100% 100%, image-set(attr(src)) 0 0/100%;
}效果如下:
image-20250823123221252
也可以疊加一層平鋪的水印。
img{
--water: url("data:image/svg+xml,%3Csvg width='150' height='150' style='transform:rotate(-45deg)' xmlns='http://www.w3.org/2000/svg'%3E%3Ctext x='50%25' y='50%25' font-size='14' fill='%23a2a9b6' font-family='system-ui, sans-serif' text-anchor='middle' dominant-baseline='middle'%3E前端偵探%3C/text%3E%3C/svg%3E");
background: var(--water) 50%/28%, image-set(attr(src)) 0 0/100%;
box-shadow: inset 0 0 0 4px rebeccapurple;
}效果如下:
image-20250823123505939
3. 圖片縮放效果
可以在不嵌套標簽的情況下實現(xiàn)圖片縮放效果。
img{
transition: .3s;
}
img:hover{
background-size: 120%;
}效果如下:
Kapture 2025-08-23 at 14.01.09
以上所有 demo 可以查看:https://codepen.io/xboxyan/pen/azvGeOV。
六、更多一種選擇
其實上面的實現(xiàn)都可以通過嵌套一層標簽來實現(xiàn),這里其實針對的是那種 html 結構不方便修改的情況,比如是框架自己生成的,或者在一些富文本編輯器了,嵌套一層會有更多的麻煩。




























