HTML + CSS 創建圖片倒影的 5 種方法

HTML + CSS 創建圖片倒影的 5 種方法

目標:掌握多種生成“圖片倒影 / Reflection”效果的實現思路,理解兼容性、性能差異與最佳實踐,方便在真實業務(商品展示、相冊、登陸頁面視覺強化)中安全使用。


總覽對比

方法核心技術代碼量兼容性動態內容適配可控性適用場景
1. -webkit-box-reflect私有 CSS 屬性最少僅 WebKit (Chrome / Safari / Edge)自動快速 Demo / 營銷頁
2. 偽元素 + transform: scaleY(-1)標準 CSS所有現代瀏覽器良好高(可自定義遮罩)通用首選
3. 偽元素 + mask-image / -webkit-maskCSS MaskSafari / Chromium (Firefox 部分實驗)良好很高(漸隱更自然)高端展示
4. SVG 復制 + 漸變遮罩內聯 SVG全面 (IE 除外)良好很高(濾鏡/形變)復雜視覺 / 批量渲染
5. Canvas 二次繪制<canvas>全面需手動重繪最高(像素級)動態生成 / 后處理

選擇建議:

  1. 追求最少代碼 & 不顧部分瀏覽器:用 1。
  2. 需要兼容性 + 易維護:用 2。
  3. 想要柔和漸隱過渡、無多余 DOM:用 3。
  4. 大型可視化 / 復雜濾鏡鏈:用 4。
  5. 需要最終導出合成圖 / 動態內容(如生成分享海報):用 5。

方法一:-webkit-box-reflect(最簡單 / 兼容性受限)

<style>.reflect-webkit {width: 240px;-webkit-box-reflect: below 6px linear-gradient(to bottom, rgba(0, 0, 0, 0.25), transparent70%);}
</style>
<img class="reflect-webkit" src="demo.jpg" alt="Product" />

說明:

  • 語法:-webkit-box-reflect: <direction> <offset> <mask>
  • linear-gradient 充當倒影的漸隱遮罩。
    優點:單行 + 自動跟隨寬高。
    缺點:僅 WebKit 內核(Firefox 不支持)。
    適合:臨時視覺增強、非核心信息。

方法二:偽元素復制 + 反轉(推薦通用方案)

思路:利用容器包裹圖片,偽元素 ::after 再繪制同一張圖像,垂直翻轉并添加漸變。

<div class="reflection-box"><img src="demo.jpg" alt="Phone" />
</div><style>.reflection-box {position: relative;width: 240px;}.reflection-box img {display: block;width: 100%;}.reflection-box::after {content: '';position: absolute;left: 0;right: 0;top: 100%;height: 100%;background: url('demo.jpg') center/cover no-repeat;transform: scaleY(-1);transform-origin: top;opacity: 0.6;/* 漸隱疊加 */mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 0.8),rgba(0, 0, 0, 0));-webkit-mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 0.8),rgba(0, 0, 0, 0));}
</style>

處理動態 src:

  • 如果圖片 URL 需動態綁定,可用行內 style="--src:url('xxx')" + background: var(--src) 或用 JS 設置偽元素。
  • 亦可直接復制 <img> 節點再 scaleY(-1),如下:
<div class="reflect-wrap"><img src="demo.jpg" alt="Phone" class="origin" /><img src="demo.jpg" alt="Phone reflection" class="mirror" />
</div><style>.reflect-wrap {width: 240px;position: relative;}.reflect-wrap .origin {display: block;width: 100%;}.reflect-wrap .mirror {display: block;width: 100%;transform: scaleY(-1);transform-origin: top;margin-top: 6px;mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.6), transparent);-webkit-mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 0.6),transparent);opacity: 0.8;}
</style>

優點:標準、兼容好、可擴展。
注意:雙份圖片會觸發兩次解碼,可用 <img decoding="async" loading="lazy"> 或復用繪制(JS 畫到 canvas 再生成 DataURL)。


方法三:偽元素 + Mask(強化漸隱 & 靈活形狀)

核心區別:不直接復制圖片,而是使用 CSS 變量引用同一來源,搭配 mask-image 形成更可控的透明衰減(可變換曲線)。

<figure class="mask-reflect" style="--src:url('demo.jpg')"><img src="demo.jpg" alt="Laptop" />
</figure><style>.mask-reflect {position: relative;width: 260px;}.mask-reflect img {width: 100%;display: block;}.mask-reflect::after {content: '';position: absolute;inset: 0;top: 100%;height: 100%;background: var(--src) center/cover no-repeat;transform: scaleY(-1);transform-origin: top;/* 自定義遮罩——使用非線性漸變模擬更柔的衰減 */mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 0.9) 0%,rgba(0, 0, 0, 0.4) 35%,rgba(0, 0, 0, 0.15) 60%,rgba(0, 0, 0, 0) 100%);-webkit-mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 0.9) 0%,rgba(0, 0, 0, 0.4) 35%,rgba(0, 0, 0, 0.15) 60%,rgba(0, 0, 0, 0) 100%);opacity: 0.85;filter: blur(0.4px) saturate(0.95);}
</style>

拓展:

  • 橫向拉伸 / 傾斜效果:附加 transform: scaleY(-1) skewX(3deg);
  • 波紋倒影:疊加 filter: url(#turbulence)(需 SVG filter)。

方法四:SVG 復制 + 漸變遮罩

適合批量渲染(一個 SVG 中包含多個倒影)或需要濾鏡(模糊、色偏、波浪)。

<svg width="260" viewBox="0 0 260 360" class="svg-reflect"><defs><linearGradient id="fade" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="black" stop-opacity="0.8" /><stop offset="70%" stop-color="black" stop-opacity="0" /></linearGradient><mask id="mask-fade" maskUnits="userSpaceOnUse"><rect x="0" y="180" width="260" height="180" fill="url(#fade)" /></mask></defs><!-- 原圖 --><image href="demo.jpg" x="0" y="0" width="260" height="180" /><!-- 倒影 --><g transform="translate(0,180) scale(1,-1)" mask="url(#mask-fade)"><image href="demo.jpg" x="0" y="0" width="260" height="180" opacity="0.9" /></g>
</svg>

優點:

  • 所有可視操作可在 SVG 內完成(模糊、波紋、顏色矩陣)。
  • 單文件可復制多份資源。
    缺點:語法冗長;與普通 DOM 混排需處理層級。

擴展濾鏡(波紋):

<filter id="ripple" x="-20%" y="-20%" width="140%" height="140%"><feTurbulence baseFrequency="0.01 0.15" numOctaves="2" result="turb"/><feDisplacementMap in2="turb" in="SourceGraphic" scale="6" xChannelSelector="R" yChannelSelector="G"/>
</filter>

然后在倒影 <g> 里加 filter="url(#ripple)"


方法五:Canvas 動態繪制(可導出 / 像素級)

適合:

  • 需要合成單張最終圖(下載 / 分享)。
  • 倒影需要與原圖進行額外像素操作(模糊、曲面映射、噪聲)。
<canvas id="c" width="260" height="360"></canvas>
<script>const img = new Image();img.src = 'demo.jpg';img.onload = () => {const h = 180;const w = 260;const canvas = document.getElementById('c');const ctx = canvas.getContext('2d');// 原圖ctx.drawImage(img, 0, 0, w, h);// 倒影:縮放坐標系ctx.save();ctx.translate(0, h * 2); // 移到下面ctx.scale(1, -1);ctx.drawImage(img, 0, 0, w, h);ctx.restore();// 漸隱:創建漸變遮罩const gradient = ctx.createLinearGradient(0, h, 0, h * 2);gradient.addColorStop(0, 'rgba(0,0,0,0.6)');gradient.addColorStop(0.7, 'rgba(0,0,0,0)');ctx.globalCompositeOperation = 'destination-in';ctx.fillStyle = gradient;ctx.fillRect(0, h, w, h);ctx.globalCompositeOperation = 'source-over';};
</script>

延伸:

  • 添加 Blur:使用離屏 canvas 再 ctx.filter = 'blur(2px)'
  • 曲面:對每一行像素裁剪后重新繪制(實現較復雜)。
  • 封裝為函數供多個圖片批量處理。

性能與內存考量

關注點說明建議
重復解碼偽元素背景與 <img> 均觸發使用緩存(同 src 瀏覽器已緩存),或使用單 <img>+CSS 復制(方法二第二種 DOM 方式)
Reflow倒影高度改變影響布局給容器固定高度 / 使用絕對定位避免抖動
重繪成本CSS 濾鏡 / SVG 濾鏡會增加渲染成本降低濾鏡強度;按需加載(IntersectionObserver)
Canvas 占用多張大圖 + 離屏操作控制尺寸,復用 canvas
動態數據src 頻繁變化Debounce 更新;避免在視口外構建倒影

常見坑 & 解決方案

問題場景解決
圖片加載時閃爍背景方式倒影先出現空白onload 后再添加反射 class
高 DPI 模糊Canvas 導出在 Retina 模糊canvas.width = cssWidth * devicePixelRatio 再縮放繪制
Mask 失效Firefox 對 mask-image 支持差異降級:在 Firefox 檢測后改用透明漸變 PNG 覆蓋
濾鏡太重卡頓多個 blur(8px)降級為較小 blur + opacity
SEO 影響額外 <img> 計入圖片索引第二種 DOM 復制時給倒影圖 aria-hidden="true" + alt=""

可復用 CSS 片段(方法二封裝)

.reflect {position: relative;display: inline-block;
}
.reflect > img {display: block;
}
.reflect::after {content: '';position: absolute;left: 0;right: 0;top: 100%;height: var(--reflect-height, 100%);background: var(--reflect-src) center/contain no-repeat;transform: scaleY(-1);transform-origin: top;opacity: var(--reflect-opacity, 0.7);mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.9), transparent);-webkit-mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 0.9),transparent);
}

使用:

<divclass="reflect"style="--reflect-src:url('demo.jpg'); --reflect-height:100%; --reflect-opacity:.6"
><img src="demo.jpg" alt="Phone" />
</div>

JS 動態設置:

const wrap = document.querySelector('.reflect');
const img = wrap.querySelector('img');
img.addEventListener('load', () => {wrap.style.setProperty('--reflect-src',`url('${img.currentSrc || img.src}')`);
});

進階創意玩法

創意說明關鍵點
波浪倒影倒影加 feTurbulence 位移SVG 過濾或 Canvas 位移
動態閃光倒影上加漸變動畫keyframes 改變 mask 的角度
顏色偏移倒影輕微冷色filter: hue-rotate(5deg) saturate(.9)
模糊加速滾動遠離時加大模糊IntersectionObserver + class 切換
多層折射多個偽元素多次縮放性能注意:限制層數

選擇決策樹(簡化)

  1. 是否需要導出最終合成圖?→ 是:Canvas。
  2. 是否需要復雜濾鏡 / 波紋?→ 是:SVG / Canvas。
  3. 是否關鍵頁面全平臺必須統一?→ 是:偽元素方案。
  4. 是否只是臨時視覺點綴且不在意 Firefox?→ -webkit-box-reflect
  5. 想要更絲滑衰減邊緣?→ 增強 Mask(方法三)。

快速小抄(Cheat Sheet)

目標推薦代碼片段
最快 Demo-webkit-box-reflect: below 4px linear-gradient(...)
通用實現偽元素 + scaleY(-1) + mask-image
柔和漸隱多段 stop 的 linear-gradient 遮罩
波紋特效SVG feTurbulence + feDisplacementMap
導出圖片Canvas 繪制 + toDataURL()
性能優化只為首屏可見元素添加倒影 / 復用 src

總結

圖片倒影本質是:復制 → 翻轉 → 衰減透明度 +(可選)附加濾鏡。選型關鍵在 兼容性、性能、是否需后處理 / 導出、視覺精細度 之間的平衡。實際項目中建議封裝成組件(接收:圖片源、倒影高度、衰減曲線、濾鏡強度),統一管理,避免隨處散落臨時寫法。

思路優先,技巧其次。掌握“復制 + 翻轉 + 遮罩”內核,再延伸任意創意。

(完)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921294.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921294.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921294.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一個文件被打開io流和不打卡 inode

1. 磁盤 最小基本單位 扇區 機器磁盤的io效率 &#xff08;讀和取&#xff09;2. 文件系統 對磁盤分區 &#xff0c;最小的文件單位塊組&#xff0c;快組內部已經劃分好區域&#xff0c;巴拉巴拉&#xff0c;總之&#xff0c;每次使用數據&#xff0c;以操作系統的處理都是塊級…

ThermoSeek:熱穩定蛋白數據庫

這篇論文提出了ThermoSeek&#xff0c;一個綜合性的網絡資源&#xff0c;用于分析來自嗜熱和嗜冷物種的蛋白質序列和結構。具體來說&#xff0c;數據收集&#xff1a;從美國國家生物技術信息中心&#xff08;NCBI&#xff09;的基因組數據庫中收集了物種的分類ID&#xff0c;并…

leetcode算法刷題的第二十七天

1.leetcode 56.合并區間 題目鏈接 class Solution { public:static bool cmp(const vector<int>& a,const vector<int>& b){return a[0]<b[0];}vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<v…

解決 Apache/WAF SSL 證書鏈不完整導致的 PKIX path building failed 問題

文章目錄解決 Apache/WAF SSL 證書鏈不完整導致的 PKIX path building failed 問題為什么會出現證書鏈錯誤&#xff1f;常見場景直連服務器正常&#xff0c;但經過 WAF 出錯Windows/Linux 下證書文件說明引入 WAF 或其他中間層&#xff1a;解決方法方法一&#xff1a;單獨配置 …

十一、標準化和軟件知識產權基礎知識

1 標準化基礎知識 1.1 基本概念 1.1.1 標準的分類 1.1.1.1 按使用范圍分類 國際標準&#xff1a;由國際組織如 ISO、IEC 制定的標準。國家標準&#xff1a;由國家標準化機構制定的標準&#xff0c;如中國的 GB&#xff0c;美國 ANSI。行業標準&#xff1a;由行業主管部門制定的…

計算機畢設選題:基于Python數據挖掘的高考志愿推薦系統

精彩專欄推薦訂閱&#xff1a;在 下方專欄&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主頁&#xff1a;計算機畢設木哥&#x1f525; &#x1f496; 文章目錄 一、項目介紹二…

什么是PCB工藝邊?獵板給您分享設計要點

什么是PCB工藝邊&#xff1f;獵板給您分享設計要點在PCB設計和制造領域&#xff0c;工藝邊是一個看似簡單卻至關重要的概念&#xff0c;它直接關系到生產流程的順暢性與最終產品的質量。本文將為您詳細解析PCB工藝邊的定義、作用、設計要點&#xff0c;并分享獵板PCB在高精度制…

Rustdesk搭建與客戶端修改與編譯

Rustdesk是一個開源的遠程桌面工具&#xff0c;客戶端可以自己定制修改編譯 這里主要記錄一下搭建的過程 服務端搭建 主要是參考了這篇文章&#xff0c;感覺作者分享~ 在 Linux VPS 上創建 RustDesk 服務器 - 知乎 https://zhuanlan.zhihu.com/p/1922729751656765374 這里主要…

數字人系統源碼搭建與定制化開發:從技術架構到落地實踐

隨著元宇宙、直播電商、智能客服等領域的爆發&#xff0c;數字人從概念走向商業化落地&#xff0c;其定制化需求也從 “單一形象展示” 升級為 “多場景交互能力”。本文將從技術底層出發&#xff0c;拆解數字人系統的源碼搭建邏輯&#xff0c;結合定制化開發中的核心痛點&…

2025國賽C題創新論文+代碼可視化 NIPT 的時點選擇與胎兒的異常判定

2025國賽C題創新論文代碼可視化 NIPT 的時點選擇與胎兒的異常判定基于多通道LED光譜優化的人體節律調節與睡眠質量評估模型摘要無創產前檢測&#xff08;NIPT&#xff09;通過分析孕婦血漿中胎兒游離DNA來篩查染色體異常&#xff0c;其準確性很大程度上依賴于胎兒Y染色體濃度的…

2021/07 JLPT聽力原文 問題一 4番

4番&#xff1a;女の人が新しい商品の紹介をしています。よく頭が痛くなる人は、どの商品を選びますか。女&#xff1a;こちら、新発売の中國茶をご案內します。今回皆様にご紹介いたしますのは、月?星?虹?空のお茶の4種類でございます。さあ、どうぞ召し上がってください。…

爆改YOLOv8 | 即插即用的AKConv讓目標檢測既輕量又提點

突破固定卷積核的局限,讓卷積核形狀隨目標變化而動態調整 目標檢測技術在當今計算機視覺領域扮演著至關重要的角色,而YOLO系列作為其中佼佼者,以其高速和高精度獲得了廣泛應用。但在實際應用中,傳統的卷積操作存在一些固有缺陷**。本文介紹了一種創新性的改進方案——AKCon…

linux inotify 功能詳解

內核宏開啟機制inotify 功能依賴 Linux 內核宏 CONFIG_INOTIFY_USER CONFIG_INOTIFY_USER=y該宏控制用戶態程序能否調用 inotify 相關系統調用,如 inotify_init(),inotify_add_watch() inotifywait 側重實時響應,適合觸發后續操作; inotifywatch 側重數據統計,適合分析事件…

Docker Registry 實現原理、適用場景、常用操作及搭建詳解

一、實現原理 Docker Registry 是基于 無狀態服務架構 的鏡像存儲與分發系統&#xff0c;其核心設計包含以下關鍵點&#xff1a;存儲驅動抽象層 Registry 通過 storagedriver.StorageDriver 接口實現存儲解耦&#xff0c;支持多種后端存儲&#xff1a; 本地存儲&#xff1a;默認…

【LeetCode熱題100道筆記】輪轉數組

題目描述 給定一個整數數組 nums&#xff0c;將數組中的元素向右輪轉 k 個位置&#xff0c;其中 k 是非負數。 示例 1: 輸入: nums [1,2,3,4,5,6,7], k 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右輪轉 1 步: [7,1,2,3,4,5,6] 向右輪轉 2 步: [6,7,1,2,3,4,5] 向右輪轉 3 步: [5,6,7…

【Linux我做主】細說進程等待

Linux進程等待Linux進程等待github地址0. 前言1. 進程等待的必要性1.1 避免僵尸進程與資源泄漏1.2 僵尸進程不可被直接清除1.3 獲取子進程的運行結果2. 進程等待的三個問題1. 為什么要有進程等待2. 進程等待是什么3. 怎么實現進程等待3. 僵尸進程演示4. waitwait的手冊聲明wait…

大語言模型對齊

大語言模型對齊的重要性與目標研究 一、引言 隨著大語言模型 (LLM) 能力的不斷提升和應用場景的日益廣泛,這些模型在為人類社會帶來巨大便利的同時,也引發了一系列關于安全性、可靠性和倫理問題的擔憂(9)。大語言模型的對齊 (alignment) 作為確保這些強大的 AI 系統與人類價…

數組(4)

int mid min (key - arr[min]) / (arr[max] - arr[min]) * (max - min);17.數組常見算法4 分塊查找18.數組常見算法5 冒泡排序筆記小程序錯誤#include<stdio.h> int main() {/*冒泡排序&#xff1a;1.相鄰的元素兩兩比較&#xff0c;大的放右邊&#xff0c;小的放左邊2…

STM32 讀寫備份寄存器

本章節功能利用備份寄存器&#xff08;BKP&#xff09;實現數據的掉電保存&#xff0c;并通過按鍵和OLED顯示屏進行交互。使能電源&#xff08;PWR&#xff09;和備份域&#xff08;BKP&#xff09;的時鐘&#xff08; RCC_APB1PeriphClockCmd 函數&#xff09;&#xff0c;并…

RabbitMinQ(模擬實現消息隊列項目)02

目錄 十.整合數據庫和文件數據 創建DiskDataManager類 十一.內存結構設計 創建MeneryDataCenter類: 實現集合操作: 對MemoryDataCenter類功能測試: 十二.整合內存和磁盤數據 創建VirtualHost類: Exchange: MSGQueue: Binding: 創建Router類 對Router類的TOPIC匹配…