codecamp

Responsive images

先决条件: 您应该已经知道 HTML的基本知识,以及如何向网页添加静态图片
目的: Learn how to use features like srcset and the <picture> element to implement responsive image solutions on websites.

为什么要用自适应的图片?

那么,我们试图用响应图像来解决什么问题? 让我们来看一个典型的场景。 一个典型的网站可能有一个标题图像,使它看起来不错的游客,加上可能一些内容图像下面。 您可能希望使标头跨越标头的整个宽度,并且内容图像适合内容列中的某处。 让我们来看一个简单的例子:

这项功能适用于宽萤幕装置,例如笔记本电脑或台式机(您可以 -responsive.html"class ="external">查看示例live ,并找到 -embedding / responsive-images / not-responsive.html"class ="external">源代码在Github上。)我们不会讨论CSS太多,除非:

  • The body content has been set to a maximum width of 1200 pixels — in viewports above that width the body remains at 1200px and centers itself in the available space. In viewports below that width, the body will stay at 100% of the width of the viewport.
  • The header image has been set so that its center always stays in the center of the header, no matter what width the heading is. So if the site is being viewed on a narrower screen, the important detail in the center of the image (the people) can still be seen, and the excess is lost off either side. It is 200px high.
  • The content images have been set so that if the body element becomes smaller than the image, the images start to shrink down so that they always stays inside the body, rather than overflowing it.

虽然这还能看,但是当你尝试在一个狭小的屏幕设备上查看本页面时,网页的头部看起来还可以,但是头部这张图片占据了屏幕的一大部分的高度,这真的很糟糕啊,而且这种情况下你仅仅只能看到人,旁边的树少了很多。

它会更好地显示一个裁剪的版本的图像,在重要的细节的镜头,当网站被看到在一个窄屏幕上,可能是一个中等宽度的屏幕设备,如平板电脑之间的东西, 这通常被称为艺术方向问题

此外,如果在微小的移动屏幕上观看,则不需要在页面上嵌入这样大的图像; 这被称为分辨率切换问题 - 光栅图像是设置的像素宽度和设置的像素数高; 正如我们在查看矢量图形时所看到的,如果光栅图像显示为大于其原始大小,则光栅图像开始看起来是颗粒和可怕的(而矢量图形 没有。)如果它显示小于其原始大小,这是浪费带宽 - 移动用户尤其不希望通过下载一个大型图像打算用于桌面,通过他们的带宽,当一个小 图像将为他们的设备。 理想的情况将是有多个分辨率可用,并根据访问网站的不同设备提供适当的大小。

为了使事情更复杂,一些设备具有高分辨率屏幕,需要更大的图像,比你可能期望他们需要,以显示得很好。 这本质上是相同的问题,但在一个稍微不同的上下文。

你可能认为矢量图像将解决这些问题,他们在一定程度上做 - 他们在文件大小和规模都很小,你应该尽可能使用它们。 它们不适合所有的图像类型,虽然它们是伟大的简单的图形,图案,界面元素等,它开始变得非常复杂,创建一个基于矢量的图像与你会发现 在说,照片。 光栅图像格式(如JPEG)更适合我们在上面示例中看到的图像类型。

这种问题在网络首次存在时并不存在,在90年代早期到中期 - 当时唯一存在的设备是浏览网页的是台式机和笔记本电脑,所以浏览器工程师和规范作者甚至不想实现 解决方案。 最近实施了响应图像技术,以解决上述问题,让您向浏览器提供几个图像文件,它们都显示相同的东西,但包含不同数量的像素( >),或适合于不同空间分配的不同图像(艺术方向)。

注意:本文中讨论的新功能 - srcset / 尺寸 / -CN / docs / Web / HTML /元素/图片"> < picture> - 都支持现代桌面和移动浏览器的发布版本 IE浏览器。)

怎样创建自适应的图片?

在本节中,我们将介绍上述两个问题,并展示如何使用HTML的响应式图像功能解决这些问题。 您应该注意到,我们将专注于HTML < img> 部分,如上例中的内容区域所示 - 网站标题中的图片仅用于装饰,因此使用CSS背景图片实现。 CSS可能拥有更好的响应式设计工具比HTML ,我们将在以后的CSS模块中讨论这些。

分辨率切换:不同尺寸

那么,我们想用分辨率切换解决什么问题? 我们想要显示相同的图片内容,根据设备的不同,只是更大或更小 - 这是我们在示例中的第二个内容图片的情况。 < img> 标准传统上只允许您将浏览器指向单个来源 文件:

<img src="elva-fairy-800w.jpg" >

不过,我们可以使用两个新属性 - srcset a href ="/ zh-CN / docs / Web / HTML / Element / img#attr-sizes"> sizes - 提供几个额外的源图片以及提示,帮助浏览器选择 一。 您可以在我们的中查看此示例 reponsive.html example on Github(see also html"class ="external">源代码):

<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" >

srcset sizes 属性看起来很复杂,但是如果你按照上面的方式对它们进行格式化,每行的属性值都有不同的部分 每个值包含逗号分隔的列表。 并且列表的每个部分由三个子部分组成。 让我们现在运行每个的内容:

srcset 定义图片集,我们将允许浏览器在每个图片之间进行选择。 在每个逗号之前,

  1. An image filename (elva-fairy-480w.jpg.)
  2. A space.
  3. The image's inherent width in pixels (480w) — note that this uses the w unit, not px as you might expect. This is the image's real size, which can be found by inspecting the image file on your computer (for example on a Mac you can select the image in Finder, and press Cmd + I to bring up the info screen.)

sizes 定义一组媒体条件(例如屏幕宽度),并指示当某些媒体条件为true时,最佳选择什么图片尺寸 - 这些是我们谈论的提示 约早。 在这种情况下,在每个逗号之前我们写

  1. a media condition ((max-width:480px)) — you'll learn more about these in the CSS topic, but for now let's just say that a media condition describes a possible state that the screen can be in. In this case, we are saying "when the viewport width is 480 pixels or less".
  2. A space.
  3. The width of the slot the image will fill when the media condition is true (440px.)

注意:对于广告位宽度,您可以提供绝对长度( px em )或相对长度(例如百分比)。 您可能已经注意到,最后一个时隙宽度没有媒体条件 - 这是在没有媒体条件为真时选择的默认值。)浏览器忽略第一个匹配条件后的所有内容,因此请小心如何排序媒体条件

所以,有了这些属性,浏览器将:

  1. Look at its device width.
  2. Work out which media condition in the sizes list is the first one to be true.
  3. Look at the slot size given to that media query.
  4. Load the image referenced in the srcset list that most closely matches the chosen slot size.

就是这样! 所以在这一点上,如果一个支持浏览器的视口宽度为480px加载页面,(max-width:480px)媒体条件将为true,因此 440px 因为 elva-fairy-480w.jpg 将被加载,因为它的固有宽度( 480w )最接近 440px >。 800px的图片是128KB的磁盘,而480px版本只有63KB - 节省了65KB。 现在想象如果这是一个有很多图片的页面。 使用这种技术可以为移动用户节省大量的带宽。

不支持这些功能的旧版浏览器将忽略它们,并加载 "> src 属性。

注意:在文档的 < head> 您会发现< meta name ="viewport"content ="width = device-width"> :强制移动浏览器采用他们真正的视口宽度来加载网页 浏览器关于它们的视口宽度,而是在更大的视口宽度加载页面,然后收缩加载的页面,这对响应式图像或设计不是非常有帮助,我们将在以后的模块中教你更多)

一些有用的开发工具

浏览器中有一些有用的开发人员工具,可帮助您确定需要使用的必要插槽宽度等。 当我开始工作时,我首先加载了我的示例的非响应版本( not-responsive.html ),然后进入 org / zh-CN / docs / Tools / Responsive_Design_Mode">响应设计视图(工具>网页开发人员>响应设计视图),允许您查看网页布局 好像他们正在通过各种不同的设备屏幕尺寸来观看。

我设置视口宽度为320px然后480px; 对于我进入 DOM检查器的每个人,点击了 -CN / docs / Web / HTML / Element / img"> < img> 元素,然后在右侧的Box Model视图选项卡中查看其大小 侧的显示。 这应该给你所需的固有图像宽度。

接下来,您可以通过将视口宽度设置为所需的宽度(例如将其设置为窄宽度)来检查 srcset 是否正常工作,打开网络检查器( Tools> Web 开发人员>网络),然后重新加载网页。 这应该给你一个下载的资产组成的网页的列表,在这里你可以检查选择哪个图像文件下载。

分辨率切换:尺寸相同,分辨率不同

如果您支持多种显示分辨率,但每个人都在屏幕上看到您的图片在真实世界的大小,您可以允许浏览器使用 srcset 和x描述符来选择合适的分辨率图片 并且没有 sizes - 一个稍微简单的语法! 您可以在 "external"> srcset-resolution.html (另请参阅 /srcset-resolutions.html"class ="external">源代码):

<img srcset="elva-fairy-320w.jpg,
             elva-fairy-480w.jpg 1.5x,
             elva-fairy-640w.jpg 2x"
     src="elva-fairy-640w.jpg" >

在此示例中 ,以下CSS应用于图像,以使其在屏幕上的宽度为320像素(也称为CSS像素):

img {
  width: 320px;
}

在这种情况下,不需要 sizes - 浏览器简单地计算出显示的是什么分辨率,并且提供在 srcset 因此,如果访问页面的设备具有标准/低分辨率显示,其中一个设备像素表示每个CSS像素,则将加载 elva-fairy-320w.jpg 图像 您不需要包括它。)如果设备具有每个CSS像素或更高的两个设备像素的高分辨率,将加载 elva-fairy-640w.jpg 图像。 640px的图片是93KB,而320px的图片只有39KB。

艺术方向

总而言之,艺术方向问题包括想要更改显示的图像以适应不同的图像显示尺寸。 例如,如果在桌面浏览器上查看时,如果在网站上显示中间有人的大横向镜头,则当在移动浏览器上查看网站时缩小,则将看起来很糟糕,因为该人将是真的很小 很难看到。 最好在移动设备上显示较小的肖像图片,以显示放大的人物。 < picture&gt ; 元素允许我们实现这种类型的解决方案。

返回我们原始的无响应 .html 示例,我们有一个非常需要艺术方向的图片:

<img src="elva-800w.jpg" >

让我们通过 < picture> 解决此问题! < video> < audio> 一样,< picture& 元素是包含几个 < source> 元素的包装, 不同的来源供浏览器选择,其次是重要的 < img> >元素。 responsive.html "中的代码 >看起来像这样:

<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" >
</picture>
  • The <source> elements include a media attribute that contains a media condition — as with the first srcset example, these conditions are tests that decide which image is shown — the first one that returns true will be displayed. In this case, If the viewport width is 799px wide or less, the first <source> element's image will be displayed. If the viewport width is 800px or more, it'll be the second one.
  • The srcset attributes contain the path to the image to display. Note that just as we saw with <img> above, <source> can take a srcset attribute with multiple images referenced, and a sizes attribute too. So you could offer multiple images via a <picture> element, but then also offer multiple resolutions of each one too. Realistically, you probably won't want to do this kind of thing very often.
  • In all cases, you must provide an <img> element, with src and alt, right before </picture>, otherwise no images will appear. This provides a default case that will apply when none of the media conditions return true (you could actually remove the second <source> element in this example), and a fallback for browsers that don't support the <picture> element.

此代码允许我们在宽屏幕和窄屏幕显示器上显示合适的图像,如下所示:

img src ="https://mdn.mozillademos.org/files/12938/picture-element-narrow.png"style ="display:block; height:710px; margin:0px auto; width:320px;">

注意:您应该仅在艺术方向场景中使用 media 属性; 当您确实使用 media 时,不要在 sizes 属性中提供媒体条件。

为什么我们不能使用CSS或JavaScript?

当浏览器开始加载页面时,它会在主解析器开始加载和解释页面的CSS和JavaScript之前开始下载(预加载)任何图像。 这是一个有用的技术,平均来说,页面加载时间减少了20%。 然而,它对响应图像没有帮助,因此需要实现像 srcset 这样的解决方案。 您无法加载 < img> 元素,然后检测视口 宽度与JavaScript和动态地更改源图像更小的,如果需要。 到那时,原始图像已经被加载,并且您将加载小图像,这在响应图像术语中甚至更糟。

    大胆使用现代图像格式

    有几种令人兴奋的新图像格式(例如WebP和JPEG-2000)可以同时保持低文件大小和高质量。 但是,浏览器支持是多斑点。

    < picture> 可让我们继续适应旧版浏览器。 您可以在 type 属性中提供MIME类型,以便浏览器可以立即拒绝不支持的文件类型:

    <picture>
      <source type="image/svg+xml" srcset="pyramid.svg">
      <source type="image/webp" srcset="pyramid.webp"> 
      <img src="pyramid.png" >
    </picture>
    
    • Do not use the media attribute, unless you also need art direction.
    • In a <source> element, you can only refer to images of the type declared in type.
    • As before, you're welcome to use comma-separated lists with srcset and sizes, as needed.

    主动学习:实现您自己的响应图像

    对于这种积极的学习,我们期待你勇敢,独自去...大部分。 我们希望您使用< picture> 和使用 srcset 的分辨率切换示例来实现您自己的适合艺术的窄屏幕/宽屏幕镜头。

    1. Write some simple HTML to contain your code (use not-responsive.html as a starting point, if you like)
    2. Find a nice wide screen landscape image with some kind of detail contained in it somewhere. Create a web-sized version of it using a graphics editor, then crop it to show a smaller part that zooms in on the detail, and create a second image (about 480px wide is good for this.)
    3. Use the <picture> element to implement an art direction picture switcher!
    4. Create multiple image files of different sizes, each showing the same picture.
    5. Use srcset/size to create a resolution switcher example, either to serve the same size image at different resolutions, or different image sizes at different viewport widths.

    注意:使用浏览器devtools来帮助确定您需要的尺寸,如上所述。

    概要

    这是一个响应图像的包装 - 我们希望你喜欢玩这些新技术。 作为一个总结,有两个不同的问题,我们在这里讨论:

    • Art direction: The problem whereby you want to serve cropped images for different layouts — for example a landscape image showing a full scene for a desktop layout, and a portrait image showing the main subject zoomed in close for a mobile layout. This can be solved using the <picture> element.
    • Resolution switching: The problem whereby you want to serve smaller image files to narrow screen devices, as they don't need huge images like desktop displays do — and also optionally that you want to serve different resolution images to high density/low density screens. This can be solved using vector graphics (SVG images), and the srcset and sizes attributes.

    这也将结束整个多媒体和嵌入模块! 在继续之前,现在唯一要做的就是尝试我们的多媒体评估,看看你是怎么做的。 玩的开心。

    也可以看看

    Adding vector graphics to the Web
    Mozilla splash page
    温馨提示
    下载编程狮App,免费阅读超1000+编程语言教程
    取消
    确定
    目录
    CSS

    关闭

    MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }