响应式图片与 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 的内容.

谢谢你看到这里😊

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java从入门到起飞(六)——用Socket实现网络通信

文章目录 背景网络编程网络编程三要素 2.DatagramSocket之UDP通信程序2.1 UDP发送数据2.2UDP接收数据2.3 3. Socket之TCP通信程序3.1TCP发送数据3.2TCP接收数据 背景 网络编程 ● 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线…

本地虚机Jumpserver使用域名访问报错 使用IP+端口没有错误

背景&#xff1a; 我在本地Windows VMware 15的环境中部署了CentOS7.5&#xff0c;下载jumpserver-offline-installer-v2.28.1-amd64-138.tar.gz并安装部署。 需求&#xff1a; 1、能使用http:ip访问堡垒机。达成&#xff1b; 2、能使用http:域名访问堡垒机。达成&#xff…

浅谈 Pytest+HttpRunner 如何展开接口测试!

软件测试有多种多样的方法和技术&#xff0c;可以从不同角度对它们进行分类。其中&#xff0c;根据软件生命周期&#xff0c;针对不同的测试对象与目标&#xff0c;可将测试过程分为 4 个阶段&#xff1a;单元测试、集成测试、系统测试和验收测试。本文着重介绍了如何借用 pyte…

Go 面向对象(匿名字段)

概述 严格意义上说&#xff0c;GO语言中没有类(class)的概念,但是我们可以将结构体比作为类&#xff0c;因为在结构体中可以添加属性&#xff08;成员&#xff09;&#xff0c;方法&#xff08;函数&#xff09;。 面向对象编程的好处比较多&#xff0c;我们先来说一下“继承…

VScode远程连接主机

一、前期准备 1、Windows安装VSCode&#xff1b; 2、在VSCode中安装PHP Debug插件&#xff1b; 3、安装好Docker 4、在容器中安装Xdebug ①写一个展现phpinfo的php文件 <?php phpinfo(); ?>②在浏览器上打开该文件 ③复制所有信息丢到Xdebug: Installation instr…

01-虚拟机安装Windows Server操作系统

1、创建并配置虚拟机 2、安装操作系统 找到windows Server镜像 等待安装 3、设置密码

vxe-table中树形结构

如图&#xff0c;同事让帮忙实现一个需求 从二级树节点开始&#xff0c;同时选中的只能有一个二级树节点&#xff0c;选中的二级树节点之下的子节点都可以被选中。否则不能被选中 直接上代码 需要注意的是&#xff0c;文中树状图传递的数据是打平的数据&#xff0c;设置代码是…

ssm+vue高校实验室管理系统源码和论文

ssmvue高校实验室管理系统源码和论文081 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 一&#xff0e;毕业设计的内容 本高校实验室管理系统采用Java语言、MySQL数据库&#xff0c;基于SSM框架进行开发设计&…

Nmap 7.94 发布:新功能!

Nmap 的最新版本 7.94 在其 26 岁生日之际发布。 最重要的升级是在所有平台上将 Zenmap 和 Ndiff 从 Python 2 迁移到 Python 3。 这个新版本的 Nmap 7.94 进行了升级&#xff0c;进行了多项改进&#xff0c;修复了一些关键错误&#xff0c;并添加了新的 Npcap、操作系统指纹…

软考:中级软件设计师:邮件加密系统,网络安全保障,网络威胁与攻击,防火墙技术

软考&#xff1a;中级软件设计师:邮件加密系统 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &…

CSS transition 过渡

1 前言 CSS过渡(transition)可以在一个元素切换到另一种状态时为其定义平滑的过渡效果。 例如&#xff0c;用户鼠标悬停在按钮上时&#xff0c;按钮颜色平滑的从一个颜色过渡到另一个颜色。 .btn:hover{background-color: red;color: black; }默认悬停效果 添加过渡效果 .b…

YOLOV8模型使用-检测-物体追踪

这个最新的物体检测模型&#xff0c;很厉害的样子&#xff0c;还有物体追踪的功能。 有官方的Python代码&#xff0c;直接上手试试就好&#xff0c;至于理论&#xff0c;有想研究在看论文了╮(╯_╰)╭ 简单介绍 YOLOv8 中可用的模型 YOLOv8 模型的每个类别中有五个模型用于检…