前言
随着显示器的快速发展,越来越多的用户更换了高分屏,我们作为Web开发者,网站内的图片尺寸都是适配普通屏幕的,如果在高分屏上图片将会变得模糊不清。
我观察了几个网站,发现他们的做法是直接用了@2x的图片,这种做法在普通屏幕上图片的一些细节会丢失。那么有没有什么办法可以兼顾普通屏幕和高分屏呢?本文就跟大家分享一种解决方案,欢迎各位感兴趣的开发者阅读本文。
基础概念
在前言中,我们提到了高分屏和**@2x**,本章节就跟大家聊一聊这两个概念。
高分屏
高分屏是指高分辨率的显示器,通常情况下我们把大于1080P分辨率的显示器称为高分屏,例如:2k、4k显示器,屏幕分辨率越高,能显示出来的像素点就越多,我们看到的画面也就更细腻。
视频的分辨率
设备像素比
上个章节中,我们讲了高分屏的概念,高分辨率下可以显示更多的像素点,那么操作系统的UI和字体就会变得非常小。
为了解决这个问题,操作系统提供了缩放选项,可以让系统UI看起来跟普通屏一样,但是显示效果更细腻。在macos中,有一个HIDPI的概念,简单来说就是用4个像素渲染1个像素。
如下图所示,我们渲染了圆的1/4,需要4x4个逻辑像素(下图左侧)。如果我们先将画面放大4倍,这个1/4的圆就要对应8x8个逻辑像素了。再将画面渲染到8x8的逻辑像素上(下图中间),最后一一对应到8x8个硬件像素上(下图右侧)。
hidpi-5.png
我们用8x8个硬件像素来渲染一个四分之一的圆,圆的面积依然没有发生改变,但是轮廓处虚化像素的数量变少了、圆的边缘显得更锐利了,肉眼看起来也就更清晰了。
4x4个逻辑像素用8x8个硬件像素来渲染,刚好扩大了2倍,我们把这个比例称为:设备像素比,可以通过window.devicePixelRatio
来获取。高分屏上获取到的值就是2,普通屏上获取到的值就是1。因此,我们就需要准备2个尺寸的图片,分别针对普通屏和高分屏。设备像素比是2,我们的图片命名后缀就可以用@2x
来标识。
本文只粗略的讲一下HIDPI,想更进一步了解的开发者请移步:谈谈 HiDPI —— 是什么,为什么,怎么做
解决方案
在web端我们要显示一个图片有两种方式:img
标签、background-image
属性。
img标签
大多数情况下,我们显示一个图片会用src属性,如下所示。
代码语言:javascript复制<img src="img/more.png" alt="" style="width: 18px; height: 18px">
在普通屏幕上这个图片看起来很正常,但是在高分屏上就会有些模糊。
image-20220720220139981
我的设备像素比是2,因此我把图片的尺寸扩大2倍,显示出来的效果就是正常的。
代码语言:javascript复制<img src="img/more@2x.png" alt="" style="width: 18px; height: 18px" >
image-20220720220403314
如果都用@2x的图片,会造成额外的带宽消耗。有没有什么方法能做到动态加载呢(高分屏用@2x,普通屏用正常图片)?
经过一番查找后,发现img标签有一个名为srcset
的属性,它的用法如下所示:
- 不同尺寸的图片用逗号隔开
- 每个尺寸的图片路径后跟一个空格写设备像素比(1x、2x)
<img src="img/more.png" alt="" style="width: 18px; height: 18px" srcset="img/more.png 1x,img/more@2x.png 2x">
这样子写了后,浏览器会根据当前屏幕的设备像素比,自动选择要加载的图片,如下所示
- 普通屏加载1x的图片
image-20220720223135753
- 高分屏加载2x的图片
image-20220720222819149
background-image属性
css的background-image属性也可以用来显示一张图片,它提供了image-set()
方法,会根据当前屏幕的设备像素比,自动选择要加载的图片。它的用法如下所示:
- image-set方法内部用url来加载图片路径
- url方法后跟一个空格写设备像素比(1x、2x)
-webkit-
为兼容写法
<style>
.img-panel {
width: 18px;
height: 18px;
background-image: image-set(url(./img/more.png) 1x, url(./img/more@2x.png) 2x);
background-image: -webkit-image-set(url(./img/more.png) 1x, url(./img/more@2x.png) 2x);
}
</style>
<body>
<div class="img-panel"></div>
</body>
同样的,浏览器会根据设备像素比选择合适的图片来加载。
- 普通屏加载1x的图片
image-20220720225444753
- 高分屏加载2x的图片
image-20220720225208927
写在最后
至此,文章就分享完毕了。
我是神奇的程序员,一位前端开发工程师。
如果你对我感兴趣,请移步我的个人网站,进一步了解。