响应式图片与 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.rhkb.cn/news/116972.html

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

相关文章

nodepad++ 插件的安装

nodepad 插件的安装 一、插件安装二、安装插件&#xff1a;Json Viewer nodepad 有 插件管理功能&#xff0c;其中有格式化json以及可以将json作为树查看的插件&#xff1a; Json Viewer 一、插件安装 1、首先下载最新的notepad 64位【https://notepad-plus.en.softonic.com…

VTK——使用ICP算法进行模型配准

ICP算法 迭代最近点&#xff08;Iterative Closest Point&#xff0c;ICP&#xff09;算法是一种用于两个三维形状之间几何对齐&#xff08;也叫做配准&#xff09;的计算方法。通常&#xff0c;这两个形状至少有一个是点云数据。ICP算法用于最小化源点云与目标点云之间点到点…

java企业工程管理系统源码之提高工程项目管理软件的效率

高效的工程项目管理软件不仅能够提高效率还应可以帮你节省成本提升利润 在工程行业中&#xff0c;管理不畅以及不良的项目执行&#xff0c;往往会导致项目延期、成本上升、回款拖后&#xff0c;最终导致项目整体盈利下降。企企管理云业财一体化的项目管理系统&#xff0c;确保…

Golang设计模式

Golang设计模式 Golang设计模式简介Golang工厂设计模式Golang单例设计模式Golang抽象工厂设计模式Golang建造者模式 (Builder Pattern)Golang 原型模式(Prototype Pattern)Golang适配器模式Golang 桥接模式&#xff08;Bridge Pattern&#xff09;Golang装饰器模式(Decorator …

Qt5界面Qt Designer上添加资源图片后,ModuleNotFoundError: No module named ‘rcc_rc‘ 的终极解决方案

在网上找了很久都没弄明白&#xff0c;最后还是自己思考解决了。 起因&#xff1a; 用 Qt Designer 添加资源文件作为背景图&#xff0c;编译 \resource\static\qrc> pyuic5 -o .\xx.py .\xx.ui发现在 xx.py 文件末尾中多了一个语句&#xff1a; import rcc_rc然后运行就…

vue项目——表情选择器

组件库地址&#xff1a;https://www.npmjs.com/package/emoji-mart-vue 1、下载 npm install --save emoji-mart-vue 2、引入 import { Picker } from emoji-mart-vueexport default {components: {Picker} }3、使用 <picker set"emojione" /> <picker …

ChatGPT 总结前端HTML, JS, Echarts都包含哪些内容

AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle, Office, Python ,ETL Excel 2021 实操,函数,图表,大屏可视化 案例实战 http://t.csdn.cn/zBytu

M1 Pro 新芯片安装python2 方案汇总

前言&#xff1a;磨刀不误砍柴工&#xff0c;环境装好&#xff0c;才能打工。M1 Pro 新芯片安装python2 文章目录 方案一 docker 容器构造环境&#xff08;如果涉及本地两个仓库需要关联则不适用&#xff09;方案二 使用 pyenv &#x1f680; 作者简介&#xff1a;作为某云服务…

thinkphp6 入门(3)--获取GET、POST请求的参数值

一、Request对象 thinkphp提供了Request对象&#xff0c;其可以 支持对全局输入变量的检测、获取和安全过滤 支持获取包括$_GET、$_POST、$_REQUEST、$_SERVER、$_SESSION、$_COOKIE、$_ENV等系统变量&#xff0c;以及文件上传信息 具体参考&#xff1a;https://www.kanclou…

Fedora Linux Flatpak 八月推荐应用

导读本文介绍了 Flathub 中可用的项目以及安装说明。 Flathub 是获取和分发适用于所有 Linux 的应用的地方。它由 Flatpak 提供支持&#xff0c;允许 Flathub 应用在几乎任何 Linux 发行版上运行。 请阅读 “Flatpak 入门”。要启用 Flathub 作为你的 Flatpak 提供商&#xff…

什么是jvm

一、初识JVM&#xff08;虚拟机&#xff09; JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Jav…

6种超简单方法告诉你卧室墙面该怎么去装饰

创意 1&#xff1a;夏日宁静 潮汐的变化并不意味着你的夏日精神也要随之改变。用海洋壁画装饰海滩吧&#xff0c;让咸咸的空气、沙滩上的脚趾和木板道上的梦想随风飘散。 创意 2&#xff1a;漂浮艺术 如果你是那种喜欢少走弯路的人&#xff0c;可以考虑完全避开 “墙面艺术&qu…

pytorch中nn.Conv1d功能介绍

在使用Conv1d函数时&#xff0c;pytorch默认你的数据是一维的&#xff0c;比如一句话“深度学习”可以用一个一维数组 [深, 度, 学, 习] 表示&#xff0c;这个数据就是一维的。图片是二维数据&#xff0c;它有长宽两个维度。 因此在使用 Conv1d 函数时&#xff0c;输入是一个三…

14:00面试,14:08就出来了,问的问题有点变态

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%,…

小白学Go 基础02-了解Go语言的诞生与演进

Go语言诞生于何时&#xff1f;它的最初设计者是谁&#xff1f;它为什么被命名为Go&#xff1f;它的设计目标是什么&#xff1f;它如今发展得怎么样&#xff1f;带着这些问题&#xff0c;我们一起穿越时空&#xff0c;回到2007年9月Go语言诞生的那一历史时刻吧。 Go语言的诞生 …

数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序

一、排序概念 将一组杂乱无章的数据按一定规律顺次排列起来。 将无序序列排成一个有序序列&#xff08;由小到大或由大到小&#xff09;的运算。 二、排序方法分类 1、按数据存储介质 名称描述内部排序数据量不大、数据在内存&#xff0c;无需内外交换存交换存储。外部排序…

【CLIP详读】

个人网站&#xff1a;https://tianfeng.space 一、前言 OpenAI的CLIP项目自从推出以来&#xff0c;CLIP引起了广泛的关注。它的方法看似简单&#xff0c;但效果非常出色&#xff0c;许多结果令人惊叹。例如&#xff0c;预训练模型可以在任何视觉分类数据集上实现出色的效果&a…

Elasticsearch 集成--Flink 框架集成

一、Flink 框架介绍 Apache Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。 Apache Spark 掀开了内存计算的先河&#xff0c;以内存作为赌注&#xff0c;赢得了内存计算的飞速发展。 但是在其火热的同时&#xff0c;开发人员发现&#xff0c;在 Spark …

【Linux】DNS系统,ICMP协议,NAPT技术

遏制自己内心的知识优越感&#xff0c;才能让你发自内心的去尊重他人&#xff0c;避免狂妄自大&#xff0c;才能让你不断的丰富自己的内心。 文章目录 一、DNS系统1.DNS服务器返回域名对应的ip2.使用dig工具分析DNS过程3.浏览器中输入url后发生的事情&#xff1f; 二、ICMP协议…

重磅OpenAI发布ChatGPT企业版本

8月29日凌晨&#xff0c;Open AI官网发布ChatGPT企业版本&#xff01; 企业版简介&#xff1a; ChatGPT企业版提供企业级安全和隐私、无限的高速 GPT-4 访问、用于处理更长输入的更长上下文窗口、高级数据分析功能、自定义选项等等。人工智能可以协助和提升我们工作生活的各个…