聊聊响应式图片
- 十一月 17, 2019
- web前端
- 没有评论
聊聊响应式图片
2016/11/14 · HTML5 · 5
评论 ·
HTML5,
响应式图片
本文作者: 伯乐在线 –
TGCode
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。
“响应式(Responsive)”这个词我想大家没有听过一千遍,也有一百遍了。响应式是指实现不同屏幕分辨率的终端上浏览网页的不同展示方式。网上介绍响应式的文章也有很多了,比如:《自适应页面设计》。在这篇文章中,我们不讲页面布局的响应式,我们主要来看看“响应式图片”。
这篇文章主要内容:
- 为什么要使用响应式图片
- <picture>元素
- img的srcset、sizes属性
1、为什么要使用响应式图片
假如有一张图片的显示宽度为200px,那么,它在 1x
(即设备像素比为 1
的显示器) 的显示器上,是占了 200
个物理像素(即实际所占的像素);它在2x
的显示器上,实际上是占了 400
个物理像素;在 3x
的显示器上,实际上是占了 600 个物理像素;在 4x
的显示器上就是占了 800 个物理像素。
如果这个图片只提供 200 像素的尺寸,那么在 2x~4x
的显示器上看起来就很模糊。如果只提供 800 像素的版本,那么在 1x~3x
的设备上会显得多余,因为加载时间会相较长,所以我们要使用响应式图片。
我们有两种方法来设置响应式图片:
- 使用<picture>元素(HTML5新增)
- 使用img的srcset、sizes
2、picture元素
在HTML
5中,增加了一个新元素<picture>。用过<video>、<audio>的,会觉得<picture>的用法很熟悉:
<picture> <source srcset=”smaller.jpg” media=”(max-width:
750px)”> <source srcset=”default.jpg”> <img
srcset=”default.jpg” /> </picture>
1
2
3
4
5
6
7
8
9
|
<picture>
<source srcset="smaller.jpg" media="(max-width: 750px)">
<source srcset="default.jpg">
<img srcset="default.jpg" />
</picture>
|
不知道你注意到没有,在 media
属性使用的语法与CSS媒体(media)特性中使用的语法一样。你可以使用相同的特性,也就是说你可以查询
max-width , min-width , max-height , min-height , orientation
等属性。
看到<picture>这个元素是不是很兴奋,可是不得不提醒你一句,目前来说,这个元素还是有兼容性问题的。
兼容性:兼容性
当然,如果你一定要使用<picture>这个元素,又要在其他浏览器里支持,那你就需要添加一个额外的插件:Picturefill2.0
<script src=”picturefill.js”></script>
1
|
<script src="picturefill.js"></script>
|
虽然<picture>很方便,但如果你考虑到兼容性,还是要谨慎使用,不过,我们也有兼容性较好的另外一种处理响应式图片的方法,看下面。
3、img的srcset、sizes属性
当然,<img>元素自身也提供了响应式的属性:srcset
和sizes
。
3.1 旧版本的srcset属性
在以前,我们是这样用的:
<img src=”width-128px.jpg” srcset=”width-128px.jpg 1x,
width-256px.jpg 2x” />
1
|
<img src="width-128px.jpg" srcset="width-128px.jpg 1x, width-256px.jpg 2x" />
|
这段代码什么意思呢?
浏览器根据屏幕不同的像素密度(x)来显示对应尺寸的图片,也可以说是根据设备的像素比来显示不同的图片。
看图:
别老是看着“别人的妹子”,请注意红色箭头,DPR就是设备像素比,不同的像素比,会显示不同的图片。
目前屏幕密度有:1x、2x、3x、4x。
3.2 新标准的srcset、sizes属性,w描述符
旧版本的srcset使用多少有些局限性,不过幸好的是到2014年,我们已经有了全新的srcset,而且还多一个size是属性。
使用新的srcset,我们只需要提供图片资源以及断点,浏览器会去自动匹配最佳显示图片。
使用方法如下:
<img src=”width-128.jpg” srcset=”width-128.jpg 128w, width-512.jpg
512w” sizes=”(max-width: 500px) 128px, 512px” />
1
|
<img src="width-128.jpg" srcset="width-128.jpg 128w, width-512.jpg 512w" sizes="(max-width: 500px) 128px, 512px" />
|
上面这段代码的意思表示:不支持srcset属性时,使用src中的图片,否则浏览器会自动匹配最佳显示图片;sizes
属性的值表示当可视区宽度不大于500像素,则图片宽度显示为128px,其他情况下,图片宽度显示为512px。。
注意:如果你用pc浏览器测试这段代码,一定要先进入移动模式,因为一打开页面时可视区大于500px(除非你的电脑是迷你版),会先显示大图片,随后即使你缩小屏幕,小图片虽然会加载,你可以在控制台的“Network”里看到,但是显示的依旧会是大图片,因为前面大图片已经缓存了,而浏览器会自动匹配最佳显示的图片。
srcset用来提供图片资源,sizes
属性的作用类似媒体查询,用来设置图片尺寸的临界点。
sizes=”[media query] [length], [media query] [length]…”
1
|
sizes="[media query] [length], [media query] [length]…"
|
要保证使用sizes
里计算出来的宽度始终是图片所占屏幕宽度(length)。
为什么说sizes
属性的作用类似媒体查询呢?
因为它只是支持部分媒体查询,比如:
(min-width: 400px) (not (orientation: landscape) ) ( (orientation:
landscape) and (min-width:400px) ) ( (orientation: portrait) or
(max-width: 500px) )
1
2
3
4
5
6
7
|
(min-width: 400px)
(not (orientation: landscape) )
( (orientation: landscape) and (min-width:400px) )
( (orientation: portrait) or (max-width: 500px) )
|
但它不支持我们明确的定义媒体类型:比如screen或者print等等。
除了使用px外,我们还可以使用em、px、cm、vw…,甚至CSS3的calc
,不能使用百分比。
sizes=”(max-width: 320px) calc(100vw – 20px), 128px”
表示当视区宽度不大于320像素时候,图片宽度为整个视区宽度减去20像素的大小。
兼容性查看:兼容性
3.3 常见的使用场景
(1)如果图片的宽度是整个视口的百分比,那么sizes可以这样设置:
sizes=”80vw”
1
|
sizes="80vw"
|
(2)假如图片两侧的边距各为10px,我们可以这样设置:
sizes=”calc( 100vw – 20px)”
1
|
sizes="calc( 100vw – 20px)"
|
(3)如果有一个两侧边距为10px的图片,允许它的最大宽度为500px,我们可以这样设置:
sizes=”( min-width:520px) 500px, calc(100vw – 20px)”
1
|
sizes="( min-width:520px) 500px, calc(100vw – 20px)"
|
上面的代码表示当可视区大于520px时,图片宽度为500px,否则宽度为calc(100vw
– 20px)计算的值。
打赏支持我写出更多好文章,谢谢!
打赏作者
原文
“响应式(Responsive)”这个词我想大家没有听过一千遍,也有一百遍了。响应式是指实现不同屏幕分辨率的终端上浏览网页的不同展示方式。网上介绍响应式的文章也有很多了,比如:《自适应页面设计》。在这篇文章中,我们不讲页面布局的响应式,我们主要来看看“响应式图片”。这篇文章主要内容:
为什么要使用响应式图片
响应式设计
所谓的响应式设计,是指在不同的屏幕分辨率,不同的像素密度比,不同宽度的终端设备中,网页布局可以自适应的调整。响应式设计的本意是使原本
PC 上的网站兼容移动终端,大部分响应式网页是通过媒体查询,加载不同样式的
CSS 文件实现的。这样的弹性化布局使网站在不同的设备终端布局都比较合理。
虽然响应式设计的好处多多,但是也有诸多缺陷。由于 PC
端和移动终端访问的是同一个网站,PC
端可以不计较流量限制,但是移动端不可能不计较。
响应式布局示意图
为适配不同终端机型的屏幕宽度和像素密度,我们一般会使用如下方法设置图片的
CSS 样式:
<style>
img{
max-width:100%;
height:auto;
}
</style>
将图片的最大宽度设置为
100%,以确保图像不会超出其父级元素的宽度,如果父级元素的宽度发生改变,图片的宽度也随之改变,height:auto
可以确保图片的宽度发生改变时,图片的高度会依据自身的宽高比例进行缩放。
这样当我们在移动设备上访问响应式网页里的图片时,只是把图片的分辨率做了缩放,下载的还是
PC
端的那张大图,这样不仅浪费流量,而且浪费带宽,而且会拖慢网页的打开速度,严重影响用户的使用体验。
打赏支持我写出更多好文章,谢谢!
任选一种支付方式
2 赞 14 收藏 5
评论
<picture>元素
新的解决方案:<picture>
<picture>
是 HTML5 的一个新元素;- 如果
<picture>
元素与当前的<audio>
,<video>
元素协同合作将增强响应式图像工作的进程,它允许在其内部设置多个<source>
标签,以指定不同的图像文件名,根据不同的条件进行加载; <picture>
可以根据不同的条件加载不同的图像,这些条件可以是视窗当前的高度(viewport),宽度(width),方向(orientation),像素密度(dpr)等;
举几个栗子
- 如下栗子中针对不同屏幕宽度加载不同的图片;当页面宽度 在 320px 到
640px 之间时加载 minpic.png;当页面宽度大于 640px 时加载 middle.png
<picture>
<source media="(min-width: 320px) and (max-width: 640px)" srcset="img/minpic.png">
<source media="(min-width: 640px)" srcset="img/middle.png">
<img src="img/picture.png" alt="this is a picture">
</picture>
2.
如下栗子中添加了屏幕的方向作为条件;当屏幕方向为横屏方向时加载_landscape.png
结尾的图片;当屏幕方向为竖屏方向时加载 _portrait.png 结尾的图片;
<picture>
<source media="(min-width: 320px) and (max-width: 640px) and (orientation: landscape)" srcset="img/minpic_landscape.png">
<source media="(min-width: 320px) and (max-width: 640px) and (orientation: portrait)" srcset="img/minpic_portrait.png">
<source media="(min-width: 640px) and (orientation: landscape)" srcset="img/middlepic_landscape.png">
<source media="(min-width: 640px) and (orientation: portrait)" srcset="img/middlepic_portrait.png">
<img src="img/picture.png" alt="this is a picture">
</picture>
-
如下栗子中添加了屏幕像素密度作为条件;当像素密度为 2x
时加载_retina.png 2x 的图片,当像素密度为 1x 时加载无 retina
后缀的图片; -
如下栗子中添加图片文件格式作为条件, 当支持 webp 格式图片时加载 webp
格式图片,当不支持时加载 png 格式图片;
5.
如下例子中添加宽度描述;页面会根据当前尺寸选择加载不大于当前宽度的最大的图片;
<img src="picture-160.png" alt="this is a picture"
sizes="90vw"
srcset="picture-160.png 160w,
picture-320.png 320w,
picture-640.png 640w,
picture-1280.png 1280w">
-
如下例子中添加 sizes 属性;当窗口宽度大于等于 800px
时加载对应版本的图片;sizes="90vw" srcset="picture-landscape-640.png 640w, picture-landscape-1280.png 1280w, picture-landscape-2560.png 2560w">
sizes="90vw" srcset="picture-160.png 160w, picture-320.png 320w, picture-640.png 640w, picture-1280.png 1280w">
兼容性:
目前只有 Chrome , Firefox , Opera 对其兼容性较好,具体兼容性如图:
兼容性示意图
优点:
- 加载适当大小的图像文件,使可用带宽得到充分利用;
- 加载不同剪裁并具有不同横纵比的图像,以适应不同宽度的布局变化;
- 加载更高的像素密度,显示更高分辨率的图像;
步骤:
- 创建
<picture></picture>
标签; - 在这些标签内创建一个你想用来执行任何一个特性的
<source></scource>
标签; - 添加一个 media
属性,用来包含你想要的特性,如宽度(max-width,min-width),方向(orientation)等; - 添加一个 srcset
属性,属性值为相应的图像文件名称,进行加载。如果你想提供不同的像素密度,例如
Retina 显示屏,可以添加额外的文件名到 srcset 属性中; - 添加一个回退的
<img>
标签;
关于作者:TGCode
路途虽远,无所畏
个人主页 ·
我的文章 ·
9 ·
img的srcset、sizes属性
<picture>
的工作原理
<picture>
语法
由上面的示例代码可知,在没有引入 js 和第三方库,CSS 中没有包含 media
queries 的情况下,<picture>
元素可以实现只用 HTML 来声明响应式图片;
<source>
元素
<picture>
标签它本身没有属性。神奇的地方是
<picture>
被用来当做<source>
的容器。
<source>
元素,是用来加载多媒体的比如视频和音频,已经被更新用到图片的加载并且一些新的属性已经被添加:
- srcset (必需)
接受单一的图片文件路径 (如:srcset=”img/minpic.png”).
或者是逗号分隔的用像素密度描述的图片路径
(如:srcset=”img/minpic.png,img/minpic_retina.png 2x”),1x
的描述是默认不使用的。
- media (可选)
接受任何验证的 media query, 你可以看到在 CSS @media 选择器
(如:media=”(min-width: 320px)”).
在之前的<picture>
语法的例子里已经用到了。
- sizes(可选)
接收单一的宽度描述 (如:sizes=”100vw”) 或者单一的 media query 宽度描述
(如:sizes=”(min-width: 320px) 100vw”).
或者逗号分隔的 media query 对宽度的描述 (如:sizes=”(min-width: 320px)
100vw, (min-width: 640px) 50vw, calc(33vw – 100px)”)
最后的一个被当做默认的。
- type(可选)
接受支持的 MIME 类型 (如: type=”image/webp” or
type=”image/vnd.ms-photo”)
浏览器会根据这些提示和属性来加载确切的图片资源。根据标签的列表顺序。浏览器会使用第一个合适的<source>
元素并忽略掉后面的<source>
标签。
- 添加最后的
<img>
元素
<img>
元素在<picture>
内部用来当浏览器不支持时或者没有源标签匹配时的显示。在
<picture>
内使用<img>
标签是必须得,如果你忘记了,将不会有图片显示出来。
用<img>
来声明默认的图片显示。将<img>
标签放到<picture>
内的最后,浏览器在找到<img>
标签之前会忽略<source>
的声明。这个图片标签也需要你写上它的
alt 属性。
1、为什么要使用响应式图片
假如有一张图片的显示宽度为200px,那么,它在 1x
(即设备像素比为 1 的显示器) 的显示器上,是占了 200
个物理像素(即实际所占的像素);它在 2x
的显示器上,实际上是占了 400 个物理像素;在 3x
的显示器上,实际上是占了 600 个物理像素;在 4x
的显示器上就是占了 800 个物理像素。
如果这个图片只提供 200 像素的尺寸,那么在 2x~4x
的显示器上看起来就很模糊。如果只提供 800 像素的版本,那么在 1x~3x
的设备上会显得多余,因为加载时间会相较长,所以我们要使用响应式图片。
我们有两种方法来设置响应式图片:
使用<picture>元素(HTML5新增)
使用img的srcset、sizes
2、picture元素
在HTML
5中,增加了一个新元素<picture>。用过<video>、<audio>的,会觉得<picture>的用法很熟悉:
<picture>
<source srcset=”smaller.jpg” media=”(max-width: 750px)”>
<source srcset=”default.jpg”>
<img srcset=”default.jpg” />
</picture>
不知道你注意到没有,在 media
属性使用的语法与CSS媒体(media)特性中使用的语法一样。你可以使用相同的特性,也就是说你可以查询
max-width , min-width , max-height , min-height , orientation
等属性。
看到<picture>这个元素是不是很兴奋,可是不得不提醒你一句,目前来说,这个元素还是有兼容性问题的。
兼容性:兼容性
当然,如果你一定要使用<picture>这个元素,又要在其他浏览器里支持,那你就需要添加一个额外的插件:Picturefill2.0(http://scottjehl.github.io/picturefill/)
<script src=”picturefill.js”></script>
虽然<picture>很方便,但如果你考虑到兼容性,还是要谨慎使用,不过,我们也有兼容性较好的另外一种处理响应式图片的方法,看下面。
3、img的srcset、sizes属性
当然,<img>元素自身也提供了响应式的属性:srcset
和sizes
。
3.1 旧版本的srcset属性
在以前,我们是这样用的:
<img src=”width-128px.jpg” srcset=”width-128px.jpg 1x,
width-256px.jpg 2x” /
No Comments, Be The First!