响应式图片与 CSS image-set

  • 响应式图片
    • 前置知识
      • art direction problem
      • 光栅图像与矢量图像 raster image and vector images
    • img 能否担此重任
      • sizes
      • srcset
      • 实际看一看
    • picture: img 的好姐妹
      • source
      • 实际看一看
    • CSS image-set
      • 语法
      • 兼容性
    • 其他注意事项

响应式图片

图片在网页中占据了 超过 60% 的浏览带宽, 因此在移动设备显示图片或者显示小图时没有必要请求原图或高清图, 同样, 在高分辨率屏幕的设备请求低分辨率的图片也不合适, 因此如何请求图片就有一些门道值得探索!

前置知识

art direction problem

上面提到了在移动设备(或窄屏幕)上显示图像时可以请求低分辨率图, 或者使用裁剪过的图片以便图片的主要信息可以显示出来, 比如将图片中的人物裁剪出来. 另外在更宽一些的屏幕, 比如平板或折叠屏上请求第二个裁剪图片. 在更宽的屏幕, 比如笔记本(laptop)或者大型显示器(desktop)请求完整图像. 这种根据设备特性显示不同图像的问题就叫做 art direction problem, 艺术指导问题.

光栅图像与矢量图像 raster image and vector images

光栅图像是定义为像素网格的图片文件, 也称为位图, 常见的光栅图像有 PNG, JPEG, GIFICO. 光栅图像通常有固定大小的尺寸, 即宽有多少像素, 高有多少像素.

矢量图像是由算法定义的, 矢量图像包含形状(shape)和路径(path)定义, 计算机可以使用这些定义来计算出图像在屏幕上应该如何显示. 如此, 矢量图即便放大或缩小, 也不会像光栅图像变得模糊或像素化.

虽然矢量图有缩放的优势, 但是它只适合非常简单的图形、图案, 一旦矢量图需要包涵很多细节, 它就会变得非常复杂.

img 能否担此重任

sizes

这个属性的值是用英文逗号分开的多个字符串, 用来指定一系列大小, 其中每个大小包含

  • 一个媒体查询条件: 媒体查询条件描述的视口(viewpoint)的属性, 而不是图片的属性. 最后一个字符串不可以有这个值
  • 一个表达大小的值:

一个合法的 sizes 的值可以是

  • (max-width: 800px) 500px, 50vw

这个值表示在媒体查询条件成立时用来展示图片的大小. 比如 (max-width: 800px) 500px 表示如果屏幕宽度小于等于 800px 时, 用来展示图片的宽度应该是 500px. 有了 500px, 浏览器就会从 srcset 中找到最匹配的使用宽度描述符的图片. 如果没有 srcset 或者 srcset 提供的值不包含宽度描述符, 那么 sizes 属性不会生效.

srcset

<img> 有一个必选的 src 属性, 当然也有一个非必选的 srcset 属性. 这个属性的值是用英文逗号分开的字符串, 用来指定浏览器可以使用的图像, 其中每个字符串都由以下部分组成

  • 图像的 URL
  • 一个空格
  • 描述符(以下之一)
    • 宽度描述符(正整数+w), 比如 480w, 其中 w 就表示像素宽度(width), 但不可以使用 px 哦😯. 宽度描述符除以 sizes 属性中给出的大小来计算有效像素密度. 📖这里的宽度指的是图片的宽度, 我们可以在操作系统上查看图片的大小.

      • 在这里插入图片描述
    • 像素密度描述符(正浮点数+x), 比如 1.5x

    • 如果没有指定描述符, 那么默认值为 1x

所以, srcset 的合法值可以是

  • red.jpeg 480w
  • red.jpeg 480w, blue.jpeg 640w

当然, 在一个 srcset 属性中不可以同时使用宽度描述符和像素密度描述符, 比如 red.jpeg 480w, blue.jpeg 2x❌. 同样的, 如果图像的描述符完全相同也不行, 比如 red.jpeg 2x, blue.jpeg 2x

如果 srcset 使用了宽度描述符, 那么 <img> 必须提供 sizes 属性, 否则 srcset 自身会被忽略.

实际看一看

浏览器是如何根据 sizessrcset 做出选择的呢?

  1. 查看设备宽度
  2. 找出 sizes 中第一个为 true 的媒体查询条件并获得设置的大小值, 比如 W
  3. 加载 srcset 中宽度和 W 相同的图片大小, 如果没有, 那么加载一个大于 W 的图片大小.

来看代码

<img 
    src="blue.png"
    alt="test image"
    sizes="
      (max-width: 200px) 100px,
      (max-width: 400px) 200px,
      (max-width: 800px) 400px,
      100px"
    srcset="
      blue.png 100w,
      green.png 200w,
      red.png 400w"
  >

见下图, 和我们想象中的一模一样. 当 viewpoint 宽度小于 200px 时匹配展示的是蓝色图片; 当 viewpoint 宽度在 200px-400px 时展示的是绿色图片; 当 viewpoint 宽度在 400px-800px 时展示红色图片
在这里插入图片描述

这里有两点需要特别说明

1️⃣ 我在 Chrome 测试时表现和预期并不一样, 直到我切换 Firefox 并且选择 DPR (物理像素/逻辑像素) 为 1, 才可以看到预期结果. 后来我在 Chrome 找到了设置 DPR 的地方. 但是如果你在开发者工具中手动拖拽改变 viewpoint 宽度也没有效果, 你必须先手动切换到某一宽度, 然后刷新页面, 才可以看到预期效果, 但是 Firefox 就不是这样, Firefox 中的效果预览是实时的.

2️⃣ 实际上这三个图片的大小是一样的, 都是 200*200, 但是我们在 srcset 写的宽度可以不同于实际宽度从而来达到选择图片的目的哦~

现在你明白了使用如果在 <img> 上配置 sizessrcset 并且一个页面中有很多图像, 那么在移动端可以节省的流量将相当可观并且网页的加载速度也将大大加快! 不支持 srcsetsizes 的旧浏览器将正常加载 src 属性指定的图像.


接下来我们要看看在不同屏幕屏幕分辨率下应该如何设置

<h1 id="devicePixelRatio"></h1>
<img 
  src="blue.png"
  alt="test image"
  srcset="
    blue.png,
    green.png 2x,
    red.png 3x
  "
>
 <div style="width: 300px; border: 1px solid red;"></div>

我们可以使用 window.devicePixelRatio 这个 API 获取有关设备物理分辨率和逻辑分辨率的比值

document.getElementById('devicePixelRatio').innerHTML = `devicePixelRatio: ${window.devicePixelRatio}`

从下图可以看出, 有一点值得注意, 就是图片实际展示的大小在不同分辨率屏幕上不同, 这三张图片大小都是 200*200, 在一倍屏上图像大小就是 200, 在二倍屏上变为 100(1/2), 在三倍屏上变为 66.67(1/3).

在这里插入图片描述

picture: img 的好姐妹

<picture> 元素包含零个或多个 <source><img> 元素来为不同的显示或设备场景提供图像.

浏览器将考虑每一个 <source> 元素并找到最匹配的, 如果没有找到匹配项或者浏览器不支持 <picture> 元素, 那么最后就展示 <img> 这个兜底元素. 因此 <picture> 就有以下的使用场景

  • art direction: 根据不同的 media 条件来裁剪或修改图像, 比如在较窄的屏幕上显示具有更多图片细节的版本
  • 提供替代的图片格式: 针对某些不支持的图片格式提供替代的图片格式. 比如较新的 AVIFWEBP 有很多优点但是浏览器可能不支持, 这时候我们需要提供 PNG 或者 JPG 版本的图片来兜底.
  • 节省带宽, 加快页面加载: 注意这个场景和 art direction 不同, 因为在节省带宽的情况是我们通常加载相同图片的低分辨率版本, 而不是像 art direction 一样裁切图片以便显示图片的细节或特定区域.

再看例子之前我们还需要多了解一下 <source>

source

<source><picture>, <audio><video> 元素提供媒体资源. <source> 标签没有结束标签并且也没有内容(即开始标签和结束标签之间的内容). <source> 通常用于为相同的媒体内容提供不同的文件格式, 以便与不同的浏览器兼容. 有几个属性需要留意

  • type: 媒体类型的 MIME 类型, 比如 image/png
    • MIME: Multipurpose Internet Mail Extensions, 多用途互联网邮件扩展类型
  • src: 资源地址, 如果父元素是 <audio><video> 那么 src 不能为空; 如果父元素是 <picture> 可以为空
  • media: 媒体查询条件. 如果父元素是 <picture> 可以有这个属性, 否则不可以有这个属性.
  • srcset: 同 <img>srcset.

回到正题, <picture> 要决定加载那个 URL, 浏览器就会检查 <source>srcset, mediatype 属性以选择最兼容的 URL 来匹配当前的布局和设备.

实际看一看

<picture>
  <source media="(orientation: portrait)" srcset="blue.png">
  <source media="(orientation: landscape)" srcset="green.png">
  <img src="blue.png" />
</picture>

可以从下图看出, 当屏幕高度大于宽度时, 显示的是蓝色图, 高度小于宽度时显示的是绿色图.
在这里插入图片描述

其实案例还可以更复杂, 就是在 srcset 中匹配不同的 DPR, 当然篇幅有限就不一一尝试了.

CSS image-set()

CSS 中也有类似根据 DPR 选择图片的函数, 那就是 image-set(), 其让浏览器从给定集合中选择最合适的 CSS 图像, 主要用于高像素密度屏幕.

语法

[ <image> | <string> ] [ <resolution> || type( <string> ) ]

  • <image>: 可以是任何合法的 CSS 图像值, 包括 url() 引入的图片或者类似 CSS 函数 linear-gradient() 这类可以创建图像的函数. 但是不可以是 image-set(), 也就是 image-set() 不支持嵌套.
  • <string>: 如果第一个参数不是 <image>, 可以直接是一个图片的 URL.
  • <resolution>: (可选) image-set() 中每个图像都必须有独一无二的 resolution 值. 其中单位包括
    • x 或 dppx: 每像素单位点数
    • dpi: 每英寸点数
    • dcpm: 每厘米点数
  • type( <string> ): (可选)图片的 MIME 类型
.box {
  width: 200px;
  height: 200px;
  background-image: image-set(
    url("https://.../blue.png") 1x type("image/png"),
    linear-gradient(45deg, lightpink, lightskyblue) 2x,
    "https://.../red.png" 3x
  );
}

在这里插入图片描述

image-set() 不像 <picture> 一样有兜底的 <img> 可选, 因此对于不支持 image-set() 的浏览器来说, 需要在使用 image-set() 之前单独设置图像. 比如,

.box {
  background-image: url("https://.../blue.png"); /** 兜底 */
  background-image: image-set(
    url("https://.../blue.png") 1x type("image/png"),
    linear-gradient(45deg, lightpink, lightskyblue) 2x,
    "https://.../red.png" 3x
  );
}

兼容性

兼容性不太好, 看来这个属性距离大面积使用还差点时间. 另外在 Firefox 90 及以后版本, 也增加了 -webkit-image-set() 作为 image-set() 的别名支持.

在这里插入图片描述

其他注意事项

在使用图片时常遇到的一个问题, 就是图片会超过父容器的宽度, 好巧不巧的是 CSSoverflow 的默认值是 visible, 就导致图像溢出, 因此可以考虑给所有的 <img> 或者 <video> 等元素设置最大宽度 (当然, <img> 的默认 displayinline, 但是一般的组件库或者 CSS 库都会修改 <img>displayblock 或者 inline-block)

img, video {
  max-width: 100%;
}

除此之外, 我们还需要为 <img> 的非必需 alt 属性提供有意义的描述, 这样做的目的是提高网页的可访问性. 通常屏幕阅读器或者其他辅助技术会读取 alt 的值以告诉用户图片展示了什么内容. 另外如果图片因为网络等其他原因无法加载时页面会展示 alt 的内容.

谢谢你看到这里😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/101684.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress(5)在主题中添加文章字数和预计阅读时间

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 样式图一、添加位置二、找到主题文件样式图 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加位置 二、找到主题文件 在主题目录下functions.php文件把下面的代码添加进去: // 文章字数…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书江西师范大学图书馆

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书江西师范大学图书馆

2021年12月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:电话号码 给你一些电话号码,请判断它们是否是一致的,即是否有某个电话是另一个电话的前缀。比如: Emergency 911 Alice 97 625 999 Bob 91 12 54 26 在这个例子中,我们不可能拨通Bob的电话,因为Emergency的电话是它的前缀,当拨…

基于BES2300YP 蓝牙耳机在线EQ调整功能设计

+他V hezkz17进数字音频系统研究开发交流答疑群(课题组) 1 BES SDK支持EQ 在运行中修改 </

vue h5项目 打包加载优化

打包美化: 1&#xff09;npx browserslistlatest --update-db 更新去除警告 2&#xff09;打包进度条 npm add progress-bar-webpack-plugin -D npm add webpackbar -D npm install --save-dev webpack-bundle-analyzer 优化&#xff1a; 1.各个插件和loader所花费的时间 …

Ubuntu22.04安装Mongodb7.0

Ubuntu安装Mongodb 1.平台支持2.安装MongoDB社区版2.1导入包管理系统使用的公钥2.2为MongoDB创建列表文件2.3重新加载本地包数据库2.4安装MongoDB包1.安装最新版MongoDB2.安装指定版MongoDB 3.运行MongoDB社区版1.目录2.配置文件3.初始化系统4.启动MongoDB5.验证MongoDB是否成功…

基于Open3D的点云处理16-特征点匹配

点云配准 将点云数据统一到一个世界坐标系的过程称之为点云配准或者点云拼接。&#xff08;registration/align&#xff09; 点云配准的过程其实就是找到同名点对&#xff1b;即找到在点云中处在真实世界同一位置的点。 常见的点云配准算法: ICP、Color ICP、Trimed-ICP 算法…

【项目】Reactor模式的服务器

目录 Reactor完整代码连接 前置知识&#xff1a; 1.普通的epoll读写有什么问题&#xff1f; 2.Connection内的回调函数是什么 3.服务器的初始化&#xff08;Connection只是使用的一个结构体&#xff09; 4.等待就绪事件&#xff1a;有事件就绪&#xff0c;对使用Connectio…

“宽带中国”城市试点与专利匹配数据,做一个多期DID(2010-2021)

数据简介&#xff1a;人类正在经历以互联网为基础的第三次技术革命&#xff0c;作为以“互联网”为底层基础的数字经济&#xff0c;以5G、人工智能和大数据中心为代表的数字基础设施建设和普惠宽带网络基础设施建设成为数字经济可持续发展的动力。工业和信息化部、国家发展和改…

stable diffusion实践操作-批次出图

系列文章目录 stable diffusion实践操作 文章目录 系列文章目录前言一、批次出图介绍1.1 webUI设置1.2 参数介绍 二、批次出图使用2.1 如何设置2.1 效果展示 总结 前言 本章主要介绍SD批次出图。 想要一次产生多张图片的时候使用。 一、批次出图介绍 1.1 webUI设置 1.2 参数…

【Mysql系列】(一)MySQL语句执行流程

首发博客地址 首发博客地址 系列文章地址 参考文章 MySQL 逻辑架构 连接器 连接命令一般是这么写的 mysql -h$ip -P$port -u$user -p 那么 什么是连接器&#xff1f; MySQL 连接器&#xff08;MySQL Connector&#xff09;是用于连接和与 MySQL 数据库进行交互的驱动程序。它提…

机器学习——决策树与随机森林

机器学习——决策树与随机森林 文章目录 前言一、决策树1.1. 原理1.2. 代码实现1.3. 网格搜索1.4. 可视化决策树 二、随机森林算法2.1. 原理2.2. 代码实现 三、补充&#xff08;过拟合与欠拟合&#xff09;总结 前言 决策树和随机森林都是常见的机器学习算法&#xff0c;用于分…

Linux字符设备中的两个重要结构体(file、inode)

https://www.cnblogs.com/chen-farsight/p/6177870.html

day-05 TCP半关闭 ----- DNS ----- 套接字的选项

一、优雅的断开套接字连接 之前套接字的断开都是单方面的。 &#xff08;一&#xff09;基于TCP的半关闭 Linux的close函数和windows的closesocket函数意味着完全断开连接。完全断开不仅不能发送数据&#xff0c;从而也不能接收数据。在某些情况下&#xff0c;通信双方的某一方…

qt相关的demo集合

自己写过的qt/c相关程序的demo集合 &#xff08;许多学习自网络中&#xff0c;很感谢大家的分享&#xff09; 源码地址&#xff1a;Qt与学习通页面: 记录与Qt相关的代码 - Gitee.com 源码目录: echart简单应用 opencv图像处理 QSetting简单使用 QtAv播放视频 ui页面 表情 超星…

构建现代应用:Java中的热门架构概览

文章目录 1. 三层架构2. Spring框架3. 微服务架构4. Java EE&#xff08;Enterprise Edition&#xff09;5. 响应式架构6. 大数据架构7. 领域驱动设计&#xff08;Domain-Driven Design&#xff0c;DDD&#xff09;8. 安卓开发架构结论 &#x1f389;欢迎来到Java学习路线专栏~…

SAP_ABAP_OLE_EXCEL批导案例

SAP ABAP顾问能力模型梳理_企业数字化建设者的博客-CSDN博客SAP Abap顾问能力模型https://blog.csdn.net/java_zhong1990/article/details/132469977 一、OLE_EXCEL批导 1.1 下载按钮 1.2 选择EXCEL上传&#xff0c;解析EXCLE数据&#xff0c; Call屏幕。 1.3 实现效果 1.4…

[管理与领导-66]:IT基层管理者 - 辅助技能 - 4- 乌卡时代(VUCA )的团队管理思维方式的转变

目录 一、乌卡时代人与公司的关系的转变 二、乌卡时代管理方式的转变 三、乌卡时代的管理与传统时代的管理比较 四、乌卡时代管理者的挑战 五、乌卡时代如何做好管理 六、个人能力要求 一、乌卡时代人与公司的关系的转变 在乌卡时代&#xff08;指虚拟办公、远程工作等数…

有c语言的基础学习python【python基础详解】

文章将从C语言出发&#xff0c;深入介绍python的基础知识&#xff0c;也包括很多python的新增知识点详解。 目录 1.python的输入输出&#xff0c;重新认识 hello world 1.1 输出函数print的规则 1.2 输入函数input的规则 1.3 用print将数据写入文件 2.数据类型、基本操作…

C++的多重继承

派生类都只有一个基类,称为单继承(Single Inheritance)。除此之外,C++也支持多继承(Multiple Inheritance),即一个派生类可以有两个或多个基类。 多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、C#、PHP 等干脆取消了多继承。 …