2-HTML多媒体与嵌入
title: 2-HTML多媒体与嵌入
tags: HTML(构建Web)
category: MDN
HTML 中的图片
怎么将一幅图片放到网页上
<img src="dinosaur.jpg">
<!--
推荐将图片都放置在 images 文件夹中
-->
<img src="images/dinosaur.jpg">
<!--
使用绝对路径;
但是这种方式是不被推荐的,这样做只会使浏览器做更多的工作,
例如重新通过 DNS 再去寻找 IP 地址。
通常我们都会把图片和 HTML 放在同一个服务器上
-->
<img src="https://www.example.com/images/dinosaur.jpg">
备选文本
<!--
alt 的值是对图片的文字描述,用于在图片无法显示或不能被看到的情况
-->
<img src="images/dinosaur.jpg"
alt="The head and torso of a dinosaur skeleton;
it has a large head with long sharp teeth">
宽度和高度
<!--
这里只是介绍了在 HTML 中修改宽高的方法,但建议在 CSS 中修改图片的宽高
-->
<img src="images/dinosaur.jpg"
alt="一只恐龙头部和躯干的骨架,它有一个巨大的头,长着锋利的牙齿。"
width="400"
height="341">
Image titles 图片标题
<!--
鼠标停留在图片上时,会给我们一个鼠标悬停提示,看起来就像链接标题
-->
<img src="images/dinosaur.jpg"
alt="一只恐龙头部和躯干的骨架,它有一个巨大的头,长着锋利的牙齿。"
width="400"
height="341"
title="A T-Rex on display in the Manchester University Museum">
<!--
然而并不推荐使用 title 属性,
因为它无法为只有键盘的用户提供服务,
以及易访问性问题等
-->
为图片搭配说明文字
<figure>
也可以是几张图片、一段代码、音视频、方程、表格或别的
<figure>
<img src="https://raw.githubusercontent.com/mdn/learning-area/master/html/multimedia-and-embedding/images-in-html/dinosaur_small.jpg"
alt="一只恐龙头部和躯干的骨架,它有一个巨大的头,长着锋利的牙齿。"
width="400"
height="341">
<figcaption>曼彻斯特大学博物馆展出的一只霸王龙的化石</figcaption>
</figure>
<!--
注意:从无障碍的角度来说,说明文字和 alt 文本扮演着不同的角色。
看得见图片的人们同样可以受益于说明文字,而 alt 文字只有在图片无法显示时才这样。
所以,说明文字和 alt 的内容不应该一样,因为当图片无法显示时,它们会同时出现。
-->
CSS 背景图片
比如,为页面中的所有段落设置一个背景图片,你可以这样做:
p {
background-image: url("images/dinosaur.jpg");
}
如果图像有意义,则应使用HTML图像。 如果图像纯粹是装饰,则应使用CSS背景图片。
视频和音频
Web 中的视频和音频
<video>
元素
<!--
<video> 嵌入一段视频;
src 属性指向你想要嵌入网页当中的视频资源;
使用 controls 来包含浏览器提供的控件界面,
同时你也可以使用合适的 JavaScript API 创建自己的界面。
界面中至少要包含开始、停止以及调整音量的功能;
<video> 标签内的内容:这个叫做后备内容
— 当浏览器不支持 <video> 标签的时候,就会显示这段内容
-->
<video src="rabbit320.webm" controls>
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
多个播放源
<video controls>
<source src="rabbit320.mp4" type="video/mp4">
<source src="rabbit320.webm" type="video/webm">
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
其他 <video>
特性
HTML5 <video>
上的特性
<!--
width 和 height
你可以用属性控制视频的尺寸,也可以用 CSS 来控制视频尺寸。
无论使用哪种方式,视频都会保持它原始的长宽比 — 也叫做纵横比。
如果你设置的尺寸没有保持视频原始长宽比,那么视频边框将会拉伸,
而未被视频内容填充的部分(即容器没有被视频填充完),将会显示默认的背景颜色
-->
<!--
autoplay
这个属性会使音频和视频内容立即播放,即使页面的其他部分还没有加载完全。
建议不要应用这个属性在你的网站上,因为用户们会比较反感自动播放的媒体文件
-->
<!--
loop
这个属性可以让音频或者视频文件循环播放。同样不建议使用,除非有必要
-->
<!--
muted
这个属性会导致媒体播放时,默认关闭声音
-->
<!--
poster
这个属性指向了一个图像的URL,这个图像会在视频播放前显示。
通常用于粗略的预览或者广告
-->
<!--
preload
这个属性被用来缓冲较大的文件,有3个值可选:
"none" :不缓冲
"auto" :页面加载后缓存媒体文件
"metadata" :仅缓冲文件的元数据
-->
<video controls width="400" height="400"
autoplay loop muted
poster="poster.png">
<source src="rabbit320.mp4" type="video/mp4">
<source src="rabbit320.webm" type="video/webm">
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
<audio>
标签
<audio>
标签与 <video>
标签的使用方式几乎完全相同,有一些细微的差别比如控制界面不同
<!--
<audio> 标签不支持 width/height 属性 — 由于其并没有视觉部件,
也就没有可以设置 width/height 的内容。
同时也不支持 poster 属性 — 同样,没有视觉部件
除此之外,<audio> 标签支持所有 <video> 标签拥有的特性
-->
<audio controls>
<source src="viper.mp3" type="audio/mp3">
<source src="viper.ogg" type="audio/ogg">
<p>你的浏览器不支持 HTML5 音频,可点击<a href="viper.mp3">此链接</a>收听。</p>
</audio>
重新播放媒体
可以在 Javascript 中调用 load() 方法来重置媒体。如果有多个由 <source>
标签指定的媒体来源,浏览器会从选择媒体来源开始重新加载媒体
const mediaElem = document.getElementById("my-media-element");
mediaElem.load();
音轨增删事件
当音轨被添加或删除时,可以通过监听相关事件来侦测到
const mediaElem = document.querySelector("video");
mediaElem.audioTracks.onaddtrack = function(event) {
audioTrackAdded(event.track);
}
显示音轨文本
.vtt
文件是一个文本文件,是用文本记录下音频的内容,具体使用如下:
1、以 .vtt 后缀名保存文件。
2、用 <track>
标签链接 .vtt 文件, <track>
标签需放在 <audio>
或 <video>
标签当中,同时需要放在所有 <source>
标签之后。
3、使用 kind 属性来指明是哪一种类型,如 subtitles 、 captions 、 descriptions。
4、然后,使用 srclang 来告诉浏览器你是用什么语言来编写的 subtitles
<!--
kind 的属性值:
subtitles
通过添加翻译字幕,来帮助那些听不懂外国语言的人们理解音频当中的内容。
captions
同步翻译对白,或是描述一些有重要信息的声音,来帮助那些不能听音频的人们理解音频中的内容。
timed descriptions
将文字转换为音频,用于服务那些有视觉障碍的人。
-->
<video controls>
<source src="example.mp4" type="video/mp4">
<source src="example.webm" type="video/webm">
<track kind="subtitles" src="subtitles_en.vtt" srclang="en">
</video>
其中 .vtt
文件格式如下:
WEBVTT
00:00.000 --> 00:04.000
别喝液氮
00:05.000 --> 00:09.000
- 它会刺穿你的胃
- 你可能会因此挂掉
文件解读:
00:00.000 --> 00:04.000 中的 00 和 04 表示的是秒数
后面跟着的字会根据格式换行
多行文本前面加 `-` 只是为了方面阅读
从对象到iframe —— 其它嵌入技术
嵌入的简史
发展历程如下:
1、使用框架创建网站 — 网站的一小部分存储于单独的HTML页面中(这样有利于下载速度 —尤其是在那时网络连接速度太慢的情况下更为明显。然而,这些技术有很多问题,随着网络速度越来越快,这些技术带来的问题远超过它们带来的积极因素)
2、插件技术变得非常受欢迎,例如Java Applet和Flash — 这些技术允许网络开发者将丰富的内容嵌入到网页中,例如视频和动画等,这些内容不能通过HTML单独实现。嵌入这些技术是通过诸如<object>
和较少使用<embed>
的元素来实现的,当时它们非常有用。但由于许多问题,包括可访问性、安全性、文件大小等,它们已经过时了
3、最后,<iframe>
元素出现了(连同其他嵌入内容的方式,如<canvas>
,<video>
等),它提供了一种将整个web页嵌入到另一个网页的方法,看起来就像那个web页是另一个网页的一个<img>
或其他元素一样
嵌入类型的使用
Youtube让我们通过<iframe>
在页面中嵌入喜欢的视频(对于其它视频网站同理,测试发现bilibili不行)
- 首先,去Youtube找一个喜欢的视频
- 在视频下方,您会看到一个共享按钮 - 点击查看共享选项
- 选择“ 嵌入”选项卡,您将得到一些 iframe 代码 - 复制一下,然后粘贴到项目中
此外,还可以试试在示例中嵌入Google地图 (需要挂代理)
- 去Google地图找一个喜欢的地图。
- 点击UI左上角的“汉堡菜单”(三条水平线)。
- 选择共享或嵌入地图选项。
- 选择嵌入地图选项,这将给你一些 iframe 代码 - 复制一下。然后粘贴到自己的项目中
iframe详解
将第三方内容嵌入网站,可能无法直接控制,但我们不希望实现自己的版本 - 例如来自在线视频提供商的视频,Disqus等评论系统,在线地图提供商,广告横幅等。本课程使用的 实时可编辑示例 就是使用
<iframe>
实现的。关于<iframe>
有一些严重的安全隐患需要考虑,但这并不意味着你不应该在你的网站上使用它们 — 它只需要一些知识和仔细地思考<!-- allowfullscreen 如果设置,<iframe>则可以通过全屏API设置为全屏模式(稍微超出本文的范围)。 frameborder 如果设置为1,则会告诉浏览器在此框架和其他框架之间绘制边框,这是默认行为。 0删除边框。不推荐这样设置,因为在CSS中可以更好地实现相同的效果。border: none; src 该属性与<video>/<img>一样包含指向要嵌入文档的URL路径。 width 和 height 这些属性指定您想要的iframe的宽度和高度。 sandbox 该属性需要在已经支持其他<iframe>功能(例如IE 10及更高版本) 但稍微更现代的浏览器上才能工作,该属性可以提高安全性设置; 备选内容 与<video>等其他类似元素相同,您可以在<iframe></iframe>标签之间包含备选内容, 如果浏览器不支持<iframe>,将会显示备选内容,这种情况下, 我们已经添加了一个到该页面的链接。现在您几乎不可能遇到任何不支持<iframe>的浏览器。 --> <iframe src="https://developer.mozilla.org/en-US/docs/Glossary" width="100%" height="500" frameborder="0" allowfullscreen sandbox> <p> <a href="https://developer.mozilla.org/en-US/docs/Glossary"> Fallback link for browsers that don't support iframes </a> </p> </iframe>
注意:为了提高速度,在主内容完成加载后,使用JavaScript设置iframe的src属性是个好主意。这使您的页面可以更快地被使用,并减少您的官方页面加载时间(重要的SEO指标)
安全隐患
在Firefox中,您会被告知:“X-Frame-Options拒绝加载https://developer.mozilla.org/en-US/docs/Glossary”。这是因为构建MDN的开发人员已经在网站页面的服务器上设置了一个不允许被嵌入到
<iframe>
的设置(请参阅配置CSP指令)这是有必要的 — 整个MDN页面被嵌入在其他页面中没有多大意义,除非您想要将其嵌入到您的网站上并将其声称为自己的内容,或尝试通过单击劫持来窃取数据,这都是非常糟糕的事情。此外,如果每个人都这样做,所有额外的带宽将花费Mozilla很多资金只有在必要时嵌入
网络安全的一个很好的经验法则是“你怎么谨慎都不为过,如果你决定要做这件事,多检查一遍;如果是别人做的,在被证明是安全的之前,都假设这是危险的。”
除了安全问题,你还应该意识到知识产权问题。无论在线内容还是离线内容,绝大部分内容都是有版权的
使用 HTTPS
HTTPS是HTTP的加密版本。您应该尽可能使用HTTPS为您的网站提供服务:
- HTTPS减少了远程内容在传输过程中被篡改的机会
- HTTPS防止嵌入式内容访问您的父文档中的内容,反之亦然
使用HTTPS需要一个安全证书,这可能是昂贵的(尽管Let’s Encrypt让这件事变得更容易),如果你没有,可以使用HTTP来为你的父文档提供服务。但是,由于HTTPS的第二个好处,无论成本如何,您绝对不能使用HTTP嵌入第三方内容
始终使用sandbox属性
一个允许包含在其里的代码以适当的方式执行或者用于测试,但不能对其他代码库(意外或恶意)造成任何损害的容器称为沙盒
如果绝对需要,您可以逐个添加权限(sandbox=""属性值内) - 请参阅sandbox所有可用选项的参考条目。其中重要的一点是,你永远不应该同时添加
allow-scripts
和allow-same-origin
到你的sandbox
属性中-在这种情况下,嵌入式内容可以绕过阻止站点执行脚本的同源安全策略,并使用JavaScript完全关闭沙盒配置CSP指令
CSP代表内容安全策略,它提供一组HTTP标头(由web服务器发送时与元数据一起发送的元数据),旨在提高HTML文档的安全性。在
<
iframe>安全性方面,您可以将服务器配置为发送适当的
X-Frame-Options` 标题。这样做可以防止其他网站在其网页中嵌入您的内容(这将导致点击和一系列其他攻击)<embed>
和<object>
元素<embed>
和<object>
元素的功能不同于<iframe>
—— 这些元素是用来嵌入多种类型的外部内容的通用嵌入工具,其中包括像Java小程序和Flash,PDF(可在浏览器中显示为一个PDF插件)这样的插件技术,甚至像视频,SVG和图像的内容注意:插件是一种对浏览器原生无法读取的内容提供访问权限的软件。
提及它们主要是为了以防您在某些情况下遇到问题,比如内部网或企业项目等
下面是一个使用该
<embed>
元素嵌入Flash影片的示例:<embed src="whoosh.swf" quality="medium" bgcolor="#ffffff" width="550" height="400" name="whoosh" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
一个
<object>
将PDF嵌入一个页面的例子:<object data="mypdf.pdf" type="application/pdf" width="800" height="1200" typemustmatch> <p>You don't have a PDF plugin, but you can <a href="myfile.pdf">download the PDF file.</a></p> </object>
我们最好是用链接指向pdf,而不是将其嵌入到网页中,以便它们可以在单独的页面上被下载或被阅读
针对插件的情况
如果您需要交互性,HTML和JavaScript可以轻松地为您完成工作,而不需要Java小程序或过时的ActiveX / BHO技术。您可以使用HTML5视频来满足媒体需求,矢量图形SVG,以及复杂图像和动画画布。对于工作Adobe Flash极少是正确的工具,除了专门的游戏和商业应用。对于ActiveX,即使微软的Edge浏览器也不再支持。
在网页中添加矢量图形
什么是矢量图形
1、位图使用像素网格来定义 — 一个位图文件精确得包含了每个像素的位置和它的色彩信息。流行的位图格式包括 Bitmap (.bmp), PNG (.png), JPEG (.jpg), and GIF (.gif.)
2、矢量图使用算法来定义 — 一个矢量图文件包含了图形和路径的定义,电脑可以根据这些定义计算出当它们在屏幕上渲染时应该呈现的样子。 SVG 格式可以让我们创造用于 Web 的精彩的矢量图形
当你放大网页的时候,区别就会变得明显起来 — 随着你的放大,PNG 图片变得像素化了,因为它存储是每个像素的颜色和位置信息 — 当它被放大时,每个像素就被放大以填满屏幕上更多的像素,所以图像就会开始变得马赛克感觉。矢量图像看起来仍然效果很好且清晰,因为无论它的尺寸如何,都使用算法来计算出图像的形状,仅仅是根据放大的倍数来调整算法中的值。
此外,矢量图形相较于同样的位图,通常拥有更小的体积,因为它们仅需储存少量的算法,而不是逐个储存每个像素的信息。
SVG是什么
SVG 是用于描述矢量图像的XML语言。 它基本上是像HTML一样的标记,只是你有许多不同的元素来定义要显示在图像中的形状,以及要应用于这些形状的效果。 SVG用于标记图形,而不是内容。 非常简单,你有一些元素来创建简单图形,如
<circle>
和<rect>
。更高级的SVG功能包括<feColorMatrix>
(使用变换矩阵转换颜色)<animate>
(矢量图形的动画部分)和<mask>
(在图像顶部应用模板)以下代码创建一个圆和一个矩形:
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"> <rect width="100%" height="100%" fill="black" /> <circle cx="150" cy="100" r="90" fill="blue" /> </svg>
但是对于复杂的图像,这很快就开始变得非常困难。 为了创建SVG图像,大多数人使用矢量图形编辑器,如 Inkscape 或 Illustrator。 这些软件包允许您使用各种图形工具创建各种插图,并创建照片的近似值(例如Inkscape的跟踪位图功能)
VG除了迄今为止所描述的以外还有其他优点:
- 矢量图像中的文本仍然可访问(这也有利于 SEO)
- SVG 可以很好地适应样式/脚本,因为图像的每个组件都是可以通过CSS或通过JavaScript编写的样式的元素
- SVG非常容易变得复杂,这意味着文件大小会增加; 复杂的SVG也会在浏览器中占用很长的处理时间
- SVG可能比栅格图像更难创建,具体取决于您尝试创建哪种图像
- 旧版浏览器不支持SVG,因此如果您需要在网站上支持旧版本的 IE,则可能不适合(SVG从IE9开始得到支持)
由于上述原因,光栅图形更适合照片那样复杂精密的图像。
将SVG添加到页面
快捷方式:
<img>
要通过
<img>
元素嵌入SVG,你只需要按照预期的方式在 src 属性中引用它。你将需要一个height或width属性(或者如果您的SVG没有固有的宽高比)<img src="equilateral.svg" alt="triangle with all three sides equal" height="87px" width="100px" />
该方法的优缺点:
优点
- 快速,熟悉的图像语法与alt属性中提供的内置文本等效。
- 可以通过在 a元素 嵌套 img元素,使图像轻松地成为超链接。
缺点
- 无法使用JavaScript操作图像。
- 如果要使用CSS控制SVG内容,则必须在SVG代码中包含内联CSS样式。 (从SVG文件调用的外部样式表不起作用)
- 不能用CSS伪类来重设图像样式(如:focus)
跨浏览器支持
对于不支持SVG(IE 8及更低版本,Android 2.3及更低版本)的浏览器,您可以从src属性引用PNG或JPG,并使用
srcset
属性 只有最近的浏览器才能识别)来引用SVG。 在这种情况下,仅支持浏览器将加载SVG - 较旧的浏览器将加载PNG:<img src="equilateral.png" alt="triangle with equal sides" srcset="equilateral.svg">
还可以使用SVG作为CSS背景图像,如下所示。 在下面的代码中,旧版浏览器会坚持他们理解的PNG,而较新的浏览器将加载SVG:
background: url("fallback.png") no-repeat center; background-image: url("image.svg"); background-size: contain;
像上面描述的
<img>
方法一样,使用 CSS 背景图像插入SVG 意味着它不能被 JavaScript 操作,并且也受到相同的 CSS 限制在HTML中引入SVG代码
还可以在文本编辑器中打开SVG文件,复制SVG代码,并将其粘贴到HTML文档中 - 这有时称为将SVG内联或内联SVG。确保您的SVG代码在
<svg></svg>
标签中(不要在外面添加任何内容)<svg width="300" height="200"> <rect width="100%" height="100%" fill="green" /> </svg>
优点:
- 将 SVG 内联减少 HTTP 请求,可以减少加载时间。
- 可以为 SVG 元素分配class和id,并使用 CSS 修改样式,无论是在SVG中,还是 HTML 文档中的 CSS 样式规则。 实际上,可以使用任何 SVG外观属性 作为CSS属性。
- 内联SVG是唯一可以让您在SVG图像上使用CSS交互(如:focus)和CSS动画的方法(即使在常规样式表中)。
- 您可以通过将 SVG 标记包在 a元素 中,使其成为超链接。
缺点:
- 这种方法只适用于在一个地方使用的SVG。多次使用会导致资源密集型维护(resource-intensive maintenance)。
- 额外的 SVG 代码会增加HTML文件的大小。
- 浏览器不能像缓存普通图片一样缓存内联SVG。
- 您可能会在 foreignObject元素 中包含回退,但支持 SVG 的浏览器仍然会下载任何后备图像。你需要考虑仅仅为支持过时的浏览器,而增加额外开销是否真的值得。
使用
<iframe>
嵌入SVG<!-- 若浏览器不支持 iframe,则会显示 img里的内容 --> <iframe src="triangle.svg" width="500" height="500" sandbox> <img src="triangle.png" alt="Triangle with three unequal sides" /> </iframe>
缺点
- 如你所知, iframe有一个回退机制,如果浏览器不支持iframe,则只会显示回退。
- 此外,除非 SVG 和您当前的网页具有相同的 origin,否则你不能在主页面上使用 JavaScript 来操纵 SVG。
自适应图片
为什么要用自适应的图片
需要解决不同设备、不同观看环境下的分辨率切换问题
你可能会认为矢量图形能解决这些问题,在某种程度上是这样的——它们无论是文件大小还是比例都合适,无论在哪里你都应该尽可能的使用它们。然而,它们并不适合所有的图片类型,虽然在简单图形、图案、界面元素等方面较好,但如果是有大量的细节的照片,创建矢量图像会变得非常复杂。
怎样创建自适应的图片
在本节中我们将专注于HTML的
<img>
,但网站页眉的图片仅是装饰性的,实际上应该要用CSS的背景图片来实现。CSS是比HTML更好的响应式设计的工具分辨率切换:不同的尺寸
可以使用两个新的属性——srcset 和 sizes——来提供更多额外的资源图像和提示,帮助浏览器选择正确的一个资源
<!-- srcset定义了我们允许浏览器选择的图像集,以及每个图像的大小。在每个逗号之前,我们写: 1、一个文件名 (elva-fairy-480w.jpg.) 2、一个空格 3、图像的固有宽度(以像素为单位)(480w)——注意到这里使用w单位,而不是你预计的px。这是图像的真实大小,可以通过检查你电脑上的图片文件找到 --> <!-- sizes定义了一组媒体条件(例如屏幕宽度)并且指明当某些媒体条件为真时,什么样的图片尺寸是最佳选择—我们在之前已经讨论了一些提示。在这种情况下,在每个逗号之前,我们写: 1、一个媒体条件((max-width:480px))——你会在 CSS topic中学到更多的。在这里,我们说“当可视窗口的宽度是480像素或更少” 2、一个空格 3、当媒体条件为真时,图像将填充的槽的宽度(440px) --> <img srcset="elva-fairy-320w.jpg 320w, elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w" sizes="(max-width: 320px) 280px, (max-width: 480px) 440px, 800px" src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
所以,有了这些属性,浏览器会:
- 查看设备宽度
- 检查sizes列表中哪个媒体条件是第一个为真
- 查看给予该媒体查询的槽大小
- 加载srcset列表中引用的最接近所选的槽大小的图像
一些有用的开发工具
1、响应式设计模式:
在 “开发者调式工具” 中,点击右上角 “手机” 样式的图案,即“响应式设计模式”,可以进入到类似手机端的视图模式,在这里可以设计不同设备上的样式适应度
2、选取页面中的元素:
在 “开发者调式工具” 中,选择左上角的 “箭头” 样式的图案,即 “选取页面中的元素”,然后点击网页中的任一元素,可以查看该元素的大小等细节
3、查看网页构件
在 “开发者调式工具” 中,选择菜单栏中的 “网络”,然后选择 “重新加载”,网络检查工具会给你一个列表,里面的文件都是已经被下载来构造网页的。然后你可以在这里看到哪个图像文件被下载了
注意: 在 Chrome 中测试时,通过如下方式禁用缓存:打开 “开发者工具” ,并选中 “网络” 下方的 “停用缓存” 的选择框。否则,Chrome 会优先选择缓存图片而不是恰好适配的那个。
分辨率切换: 相同的尺寸, 不同的分辨率
如果你支持多种分辨率显示,但希望每个人在屏幕上看到的图片的实际尺寸是相同的,你可以让浏览器通过srcset和x语法结合——一种更简单的语法——而不用sizes,来选择适当分辨率的图片
<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">
在这种情况下,sizes并不需要——浏览器只是计算出正在显示的显示器的分辨率,然后提供srcset引用的最适合的图像。因此,如果访问页面的设备具有标准/低分辨率显示,一个设备像素表示一个CSS像素,
elva-fairy-320w.jpg
会被加载(1x 是默认值,所以你不需要写出来)。如果设备有高分辨率,两个或更多的设备像素表示一个CSS像素,elva-fairy-640w.jpg
会被加载美术设计
美术设计问题涉及要更改显示的图像以适应不同的图像显示尺寸。
<picture>
元素允许我们这样实现<!-- media属性 这一属性包含一个媒体条件,这些条件来决定哪张图片会显示——第一个条件返回真, 那么就会显示这张图片。在这种情况下,如果视窗的宽度为799px或更少, 第一个<source>元素的图片就会显示。如果视窗的宽度是800px或更大,就显示第二张图片 --> <!-- srcset属性 包含要显示图片的路径。请注意,正如我们在<img>上面看到的那样, <source>可以使用引用多个图像的srcset属性,还有sizes属性。 所以你可以通过一个 <picture>元素提供多个图片,不过也可以给每个图片提供多分辨率的图片。 --> <!-- 在任何情况下,你都必须在 </picture>之前正确提供一个<img>元素以及它的src和alt属性, 否则不会有图片显示。当媒体条件都不返回真的时候,它会提供图片; 如果浏览器不支持 <picture>元素时,它可以作为后备方案 --> <picture> <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg"> <source media="(min-width: 800px)" srcset="elva-800w.jpg"> <img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva"> </picture>
注意: 你应该仅仅当在美术设计场景下使用media属性;当你使用media时,不要在sizes属性中也提供媒体条件
为什么不能使用 CSS 或 JS 自适应图片
因为你不能先加载好
<img>
元素后, 再用 JavaScript 检测可视窗口的宽度,如果觉得大小不合适,再动态地加载小的图片替换已经加载好的图片,这样的话, 原始的图像已经被加载了, 然后你又加载了小的图像, 这样的做法对于响应式图像的理念来说,是很糟糕的使用现代图像格式
有很多令人激动的新图像格式(例如WebP和JPEG-2000)可以在有高质量的同时有较低的文件大小。然而,浏览器对其的支持参差不齐
<picture>
让我们能继续满足老式浏览器的需要。你可以在type
属性中提供MIME类型,这样浏览器就能立即拒绝其不支持的文件类型:`<!-- 不要使用media属性,除非你也需要美术设计。 在<source> 元素中,你只可以引用在type中声明的文件类型。 像之前一样,如果必要,你可以在srcset和sizes中使用逗号分割的列表 --> <picture> <source type="image/svg+xml" srcset="pyramid.svg"> <source type="image/webp" srcset="pyramid.webp"> <img src="pyramid.png" alt="regular pyramid built from four equilateral triangles"> </picture>