大白话说Web图片开发——像素到响应式
前言
你是否遇到过这些Web图片的开发问题:
图片的尺寸不符合预期,不知道怎样去调整它图片在某些设备上的清晰度太低,涉及到设备像素密度、分辨率、PPI、DPR、物理像素、逻辑像素一大堆概念实在太复杂难以搞明白图片响应式的响应式切换不符合预期,不知道该怎样调整这些就是本文要解决的问题,本文会涉及到一点点像素相关的概念但是绝不会深究这些概念以免搞乱~
同样,本文也不会深究浏览器如何读取图片数据元以及渲染它为一个一个到像素点等这些浏览器底层问题~
本文想要说明的: 图片的尺寸响应式和分辨率切换问题!
好了,现在让我们开始吧!
图片尺寸
注: 请仔细观察图片的宽高变化,这对理解他们的关系很重要!
我们如何把一个图片URL或者图像数据展示在浏览器中?浏览器提供给了我们img标签和对应的接口,我们通常只需要:
<img src="elva-fairy-640w.jpg" />
很神奇,这样我们就可以直接在浏览器中看到我们的图片了,我们甚至没有给它宽度和高度,它就已经可以自动的显示出来,现在我们来对它做一点调整!
这里图片宽高为640 * 427 (这是图片原本展示的宽高)
让它最终展示的宽高为200 * 200
如何实现这个效果呢?
直接修改img标签的宽高:// css: img { height: 200px; width: 200px;}
外层嵌套一个div,然后img的宽高设置为100% <div><img src="elva-fairy-640w.jpg" /></div><style> div { width: 200px; height: 200px; } img { width: 100%; height: 100%; }</style>
我们代码的最终效果如下:
这是当我们想要修改图片的尺寸时,我们可以这样做,所以我们可以来做一个小结,我们改变图片尺寸大小的方法可以是:
修改img标签尺寸修改包裹img标签的容器尺寸它们之间的关系,应该是这样的:
当我们的 最外层容器, img标签没有对图片自身有约束时,图片默认的宽高就是读取的是图片自身的数据的宽高(这里备注下: 图片自身的宽高可以理解为图片自身包含的一个一个的像素点的个数,可以通过javascript提供的naturalWidth和anturalHeight查看)!!
而一旦我们通过 CSS的方式修改了这二者,那么浏览器会自动的根据伸缩算法,让我们的图片发生这种压缩现象!!
所以,很多时候我们图片的尺寸调整不对劲并不是我们前端的CSS不熟练(你CSS抡冒烟了都没用…),而是图片自身的尺寸问题!!!
页面响应式图片尺寸
当我们希望我们的图片不要向上面一样被粗暴的直接修改尺寸,我们更希望根据 页面大小变化来调整我们图片的尺寸!!
这时就要引入img标签的属性srcset
和 sizes
——来提供额外的资源图像和提示,帮助浏览器选择最合适的资源。
<img srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w" sizes="(max-width: 600px) 480px, 800px" src="elva-fairy-800w.jpg" />
具体的属性作用参考MDN这里不再赘述,我们现在只需要知道通过这两个属性,我们可以告诉浏览器我们希望在屏幕宽度小于600px时使用elva-fairy-480w.jpg这张图片即可,而这张 图片自身的宽高是符合我们的预期的!!
这就给我们在不同的屏幕尺寸大小下展示完全不同的图片!!
内容响应式图片
除了设定根据页面尺寸大小切换图片,包裹着图片自身的img标签(不清楚看上面的图)也是可以响应式的,我们希望可以控制图片自身在这个盒子中的位置、伸缩与否等等来让图片更好的填充img标签!!!
这里就需要引出我们要介绍的两个css属性:
object-fit
CSS 属性指定可替换元素的内容应该如何适应到其使用高度和宽度确定的框。
效果如下:
object-position
属性来切换被替换元素的内容对象在元素框内的对齐方式。
效果如下:
注: 背景图片类比: background-size & background-position
图片的清晰度
图片是否清晰也是我们开发Web图片的一个重要的问题, 但是每当我们想要弄清楚这里的问题时,总是会有一些诸如设备像素密度、分辨率、PPI、DPR、物理像素、逻辑像素一大堆概念阻挡着我们,以至于我们忘记了最初我们想要干什么,而实际上我们只想要告诉浏览器,嘿man,让我的图片清晰度高一点!!!
所以,我尝试跳过这些复杂的概念,我们直接从最最最原始来分析!!!
注: 这里就不介绍图片的分类了(可以之后说),下面我们讨论的都是光栅图哈!
图片的呈现
一个图片最终要渲染到页面上,它其实经历了这些流程:
这里重点在于 像素点的对应, 一个一个被解析后的图片二进制数据流变成了一个一个的像素点被这样子对应到了屏幕上的像素点,而只要对应到屏幕上的像素点个数 >= 浏览器解析后的图片的一个一个像素点, 那么这个时候我们人眼就会觉得清晰!!, 并且随着最终我们展示到屏幕上的像素点个数增大,那么显然,我们就会觉得这个图片会越来越清晰!!!
所以,我们可以得出结论,我们让一个图片清晰的方式可以有下面两种方式:
改变图片自身,让得到的图片本身像素点增加 & 保证对应到屏幕上像素点也增加2.改变屏幕上的像素,我们不动解析后的图片像素点个数,比如我们可以让渲染到屏幕上的像素点是二倍,我两个屏幕像素渲染原来一个图片的像素即可(所以就变的更清晰)
切换不同分辨率图片
这里同样要引入上面提到过的srcset属性,代码如下:
<img srcset="elva-fairy-320w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-640w.jpg 2x" src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy" /> <img srcset="elva-fairy-640w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-320w.jpg 2x" src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy" /> img { width: 320px; }
这里我们调换了在设备像素比为1时的顺序,也就是浏览器解析图片的像素点个数,显然2大于1的个数,所以最终我们可以很清晰的看到,2的清晰度要更高!!!
总结和最佳实践
按照以下步骤来:
确认好你想要响应式的是图片的什么?
图片的尺寸大小
直接使用srcset + sizes属性实现, easy!picture标签+ source标签+img实现, easy!图片的分辨率
srcset配置好对应的像素密度参数即可实现, easy!图片在容器中展示的大小比例
修改图片内容元素在img标签中的展示宽高效果 =》直接修改img标签的宽高以及图片内容益处的策略,easy!
修改容纳img标签的盒子, 定义img元素在盒子中的表现形式即可,easy!
object-fitobject-positionbackground-positionbackground-size修改图片方向、缩放算法等,complex(下面说…)
其它图片操作
调整浏览器渲染的图片的预设方向——image-orientation
属性值如下:
from-image: 根据图片的EXIF数据来修正图片的旋转方向一个角度大小: 图片的旋转值(四舍五入到90deg的整数倍)flig: 图片水平翻转调整浏览器对图片的缩放操作——image-rendering
触发条件:
每一个图片资源都会有它默认的尺寸,但是开发者通常会指定一个图片的width和height,一旦二者不匹配浏览器会自动的进行缩放操作,此时,我们可以通过image-rendering属性来操作缩放.
属性值如下:
auto: 默认缩放规则smooth: 应使用能最大化图像客观观感的算法来缩放图像high-quality: 除了客观的感官外,高质量的缩放优先crisp-edges: 必须使用可有效保留对比度和图像中的边缘的算法来对图像进行缩放,并且,该算法既不会平滑颜色,又不会在处理过程中为图像引入模糊。合适的算法包括最近邻居(nearest-neighbor)算法和其他非平滑缩放算法,比如 2×SaI 和 hqx-* 系列算法。此属性值适用于像素艺术作品,例如一些网页游戏中的图像。pixelated: 放大图像时,使用最近邻居算法,因此,图像看着像是由大块像素组成的。缩小图像时,算法与auto
相同。 auto、pixelated、crisp-edges区别:
设置图像的分辨率——image-resolution
注: 先声明, 这个属性是一个实验性质的,不要在production中使用
在默认情况下, 浏览器会根据图片的naturalHeight和naturalWidth来对应着去渲染图片到页面上,但是我们可以通过这个属性来调整物理像素和css像素px之间的对应关系
from-image: 默认一句图像的分辨率具体的值: 指定按照多少分辨率对应组合起来: 默认按照图像,没有再按照具体的来对应