最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
HTML怎样做Retina适配_高清屏Retina适配方法【建议收藏】
时间:2026-06-27 10:08:52 编辑:袖梨 来源:一聚教程网
Retina适配核心是解决逻辑像素与物理像素不匹配问题:canvas需同步设置width/height和CSS尺寸并scale;img用srcset适配像素密度、picture兼顾视口宽度;CSS背景图优先-webkit-image-set();0.5px边框须JS检测支持。
Retina 适配不是“加个 srcset 就完事”,核心矛盾是:**逻辑像素(CSS 像素)和物理像素不匹配**。只改显示尺寸、不改渲染缓冲区,图就糊;只换图、不处理 canvas 或背景图缩放,照样虚。
canvas 在 Retina 屏上模糊?必须同步改 width/height 和 CSS 尺寸
Canvas 渲染模糊的根源,90% 是只设置了 canvas.style.width 和 canvas.style.height,却没碰 canvas.width 和 canvas.height 这两个 DOM 属性。
DOM 属性决定绘图缓冲区大小(即实际绘制分辨率),CSS 样式只控制它在页面上“占多大地方”。两者不一致 = 拉伸低清图。
- 初始化时必须按
window.devicePixelRatio缩放:const dpr = window.devicePixelRatio || 1;canvas.width = Math.floor(width * dpr);canvas.height = Math.floor(height * dpr);canvas.style.width = width + 'px';canvas.style.height = height + 'px';
- 绘图前调用
ctx.scale(dpr, dpr),否则所有坐标都要手动乘dpr,极易出错 - 监听
resize和orientationchange,iOS 旋转后dpr可能不变但布局重排,需重新计算
img 标签用 srcset 还是 <picture>?看是否要响应视口宽度 + 像素密度双重条件
单纯适配高分屏(同一尺寸下选 1x/2x 图),srcset 足够;但若还要根据屏幕宽度切图(比如手机用 400w、桌面用 1200w),就得用 <picture>。
立即学习“前端免费学习笔记(深入)”;
-
<img src="icon.png" srcset="[email protected] 2x">:fallback 依赖src,老浏览器也能降级显示 -
<picture>中<source media="(min-width:768px)" srcset="[email protected] 1x, [email protected] 2x">:先匹配media,再在匹配的<source>内按srcset选图 - Webpack/Vite 构建时静态资源路径不会自动补
@2x后缀,得靠插件(如vite-plugin-imagemin)或自定义 resolve 规则,否则 2x 图 404
CSS 背景图适配 Retina?优先用 -webkit-image-set(),媒体查询是备选
-webkit-image-set() 是目前最简洁可控的方式,原生支持 1x/2x/3x 多倍图声明,且无需 JS 干预。
典型写法:
div { background-image: -webkit-image-set( url(icon.png) 1x, url([email protected]) 2x, url([email protected]) 3x );}
- 注意:Safari 15.4+、Chrome 93+、Firefox 103+ 支持标准语法
image-set(),但兼容性仍不如-webkit-image-set()稳定 - 媒体查询方案(
@media (-webkit-min-device-pixel-ratio: 2))需要重复写整套背景规则,维护成本高 - 无论哪种方式,
background-size必须设为逻辑尺寸(如16px 16px),否则高分图会撑大容器
1px 边框在 Retina 上变粗?别硬写 0.5px,先检测支持再启用
0.5px 在 iOS 7、Android 4.x 等旧系统会被解析为 0px,直接消失。不能无脑写。
正确做法是用 JS 检测浏览器是否真正支持:
if (window.devicePixelRatio >= 2) { const test = document.createElement('div'); test.style.border = '.5px solid transparent'; document.body.appendChild(test); if (test.offsetHeight === 1) { document.documentElement.classList.add('hairlines'); } document.body.removeChild(test);}
- 检测必须在 DOM ready 后执行,且不能放在
DOMContentLoaded之前 - 后续样式写成
.hairlines .border-1px { border: 0.5px solid #ccc; },未通过检测的设备 fallback 到 1px - 伪元素 +
transform: scaleY(0.5)是更通用的 fallback 方案,但要注意父容器overflow: hidden可能裁剪
真正难的不是写对某一行代码,而是意识到:Retina 适配是个贯穿 HTML、CSS、JS、构建流程的链路问题。canvas 的 width/height、img 的 srcset fallback、CSS 的 image-set 兼容性、构建工具对 @2x 资源的识别——漏掉任意一环,都会在某个设备上突然糊掉。