如何使div始终固定在背景视频/图像的指定位置?
问题
项目里背景视频靠object-fit: cover缩放铺满100%屏幕(边缘会被裁剪),要在视频的几个兴趣点上放div来处理hover事件,但窗口调整大小时,div没法固定在目标位置。已知视频的宽高比。
附示例代码(用图片替代视频演示需求:蓝色div始终固定在山峰顶端,不受图像尺寸变化影响):
.son1 { width: 20px; height: 20px; background: blue; position: absolute; padding: 10px; left: 100px; top: 160px; } img { height: 100vh; width: 100%; object-fit: cover; position: absolute; border-style: solid; }
<html> <head> <title>Check this</title> </head> <body> <div> <img src="https://images.all-free-download.com/images/graphiclarge/evening_landscape_210502.jpg"> <div class="son1"></div> </div> </body> </html>
解决方案
核心逻辑
object-fit: cover是优先让媒体填满容器、超出部分裁剪的缩放规则。要让定位div跟着目标点走,得先算出容器和媒体的实际缩放比例、偏移量,再把目标点在媒体原始尺寸里的百分比位置,换算成容器内的绝对坐标。
实现步骤
- 把媒体和定位div放在同一个相对定位容器里,确保定位基准统一。
- 根据媒体原始宽高比和容器尺寸,计算媒体实际显示的大小、偏移量。
- 用百分比记录目标点在媒体原始图中的位置,窗口变化时重新计算div的绝对位置。
完整代码实现
HTML
<div class="media-container"> <img src="https://images.all-free-download.com/images/graphiclarge/evening_landscape_210502.jpg" class="bg-media"> <div class="interest-point" data-x="62%" data-y="28%"></div> </div>
CSS
.media-container { position: relative; width: 100vw; height: 100vh; overflow: hidden; } .bg-media { width: 100%; height: 100%; object-fit: cover; } .interest-point { position: absolute; width: 20px; height: 20px; background: blue; padding: 10px; transform: translate(-50%, -50%); /* 让div中心对准目标点 */ cursor: pointer; }
JavaScript
// 替换成你的视频实际宽高比(示例为1920*1080的16:9) const mediaAspectRatio = 1920 / 1080; function updateInterestPoints() { const container = document.querySelector('.media-container'); const containerWidth = container.offsetWidth; const containerHeight = container.offsetHeight; const containerAspect = containerWidth / containerHeight; let mediaWidth, mediaHeight, offsetX, offsetY; if (containerAspect > mediaAspectRatio) { // 容器更宽,媒体高度铺满,宽度超出裁剪 mediaHeight = containerHeight; mediaWidth = mediaHeight * mediaAspectRatio; offsetX = (containerWidth - mediaWidth) / 2; offsetY = 0; } else { // 容器更高,媒体宽度铺满,高度超出裁剪 mediaWidth = containerWidth; mediaHeight = mediaWidth / mediaAspectRatio; offsetX = 0; offsetY = (containerHeight - mediaHeight) / 2; } // 更新所有兴趣点位置 document.querySelectorAll('.interest-point').forEach(point => { const xPercent = parseFloat(point.dataset.x) / 100; const yPercent = parseFloat(point.dataset.y) / 100; const absoluteX = offsetX + (mediaWidth * xPercent); const absoluteY = offsetY + (mediaHeight * yPercent); point.style.left = `${absoluteX}px`; point.style.top = `${absoluteY}px`; }); } // 初始化+窗口 resize 时触发更新 window.addEventListener('load', updateInterestPoints); window.addEventListener('resize', updateInterestPoints);
关键说明
- 宽高比替换:把
mediaAspectRatio改成你的视频实际宽高比(比如4/3、9/16等)。 - 兴趣点坐标:通过
data-x和data-y设置目标点在媒体原始图中的百分比位置(示例中山峰顶端在原始图的62%宽度、28%高度处)。 - 中心定位:
translate(-50%, -50%)让div的中心对准目标点,比左上角定位更精准。 - 实时更新:监听窗口resize事件,每次尺寸变化都重新计算位置,保证div始终对准目标点。
内容的提问来源于stack exchange,提问作者Rahul Bir
相关产品推荐
相关产品推荐

