如何在CSS中实现基于图片颜色的div悬停渐变背景效果
解决方案
要实现鼠标悬停时,基于图片颜色生成渐变模糊背景的效果,我们需要结合CSS伪元素、CSS变量和JavaScript颜色提取来完成。以下是完整实现:
完整代码
HTML
<div style=" display: grid; grid-template-columns: 250px 250px 250px 250px 250px; column-gap: 20px; margin-left: 50px; margin-right: 10px"> <div class="grid1"> <div> <img class="pictures" src="https://cdn.pixabay.com/photo/2015/04/19/08/32/marguerite-729510__340.jpg"> </div> <div> <p class="title"> WNEO 88.3 PM 30 Max PL-XVII/Lluv Quest; </p> <p class="info"> <i>- Non lo so, - rispose Tsukuru. - Lui e io viviamo in mondi lontani anni luce. Non è facile capire per me se fa bene o male.</i> </p> </div> </div> </div>
CSS
.grid1 { position: relative; overflow: hidden; border-radius: 20px; transition: all 0.3s ease; background: #fff; /* 默认背景 */ } .grid1:hover { box-shadow: 3px 3px 0px black; cursor: pointer; } /* 悬停时显示的模糊渐变背景 */ .grid1:hover::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, var(--color1), var(--color2)), var(--img-url); background-size: cover; background-position: center; background-blend-mode: overlay; /* 混合渐变与模糊图片 */ filter: blur(8px); z-index: 0; opacity: 0.9; } /* 图片半透明化,让背景透出 */ .grid1:hover img { opacity: 0.3; transition: opacity 0.3s ease; } /* 确保文本在背景上层 */ .grid1 > div { position: relative; z-index: 1; padding: 0 10px 10px; } img { width: 100%; display: block; border-radius: 20px 20px 0 0; transition: opacity 0.3s ease; } .title { font-weight: bold; margin: 10px 0; } .info { font-size: 0.9em; color: #555; }
JavaScript
// 提取图片的主色调和深色变体 function getDominantColors(img) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; let r = 0, g = 0, b = 0; let count = 0; // 每隔10个像素采样一次,提升性能 for (let i = 0; i < data.length; i += 40) { r += data[i]; g += data[i + 1]; b += data[i + 2]; count++; } // 计算平均主色调 const avgR = Math.floor(r / count); const avgG = Math.floor(g / count); const avgB = Math.floor(b / count); // 生成一个稍暗的变体作为渐变的另一端 const darkerR = Math.floor(avgR * 0.7); const darkerG = Math.floor(avgG * 0.7); const darkerB = Math.floor(avgB * 0.7); return [`rgb(${avgR}, ${avgG}, ${avgB})`, `rgb(${darkerR}, ${darkerG}, ${darkerB})`]; } document.addEventListener('DOMContentLoaded', () => { const gridItems = document.querySelectorAll('.grid1'); gridItems.forEach(item => { const img = item.querySelector('img'); // 等待图片加载完成后提取颜色 const handleImageLoad = () => { const [color1, color2] = getDominantColors(img); item.style.setProperty('--color1', color1); item.style.setProperty('--color2', color2); item.style.setProperty('--img-url', `url(${img.src})`); }; if (img.complete) { handleImageLoad(); } else { img.addEventListener('load', handleImageLoad); } }); });
关键说明
- CSS伪元素: 使用
::before创建覆盖整个.grid1的背景层,悬停时显示。通过filter: blur(8px)实现模糊效果。 - CSS变量: 利用JavaScript提取图片颜色后,将颜色和图片URL存入CSS变量,供伪元素的渐变和背景使用。
- 背景混合: 使用
background-blend-mode: overlay将渐变与模糊图片混合,形成贴合图片风格的渐变背景。 - 图片透明度: 悬停时降低图片透明度,让背景层的渐变模糊效果透出,同时保持文本清晰可见。
- 颜色提取: 通过Canvas获取图片像素数据,计算平均主色调并生成深色变体,确保渐变自然匹配图片风格。
你可以根据需求调整blur值、background-blend-mode(如multiply、screen)或渐变角度,以达到理想效果。
内容的提问来源于stack exchange,提问作者mvrmoris
相关产品推荐
相关产品推荐

