Responsive images

2018-05-15 17:26 更新
先決條件: 您應(yīng)該已經(jīng)知道 HTML的基本知識,以及如何向網(wǎng)頁添加靜態(tài)圖片
目的: Learn how to use features like srcset and the <picture> element to implement responsive image solutions on websites.

為什么要用自適應(yīng)的圖片?

那么,我們試圖用響應(yīng)圖像來解決什么問題? 讓我們來看一個典型的場景。 一個典型的網(wǎng)站可能有一個標(biāo)題圖像,使它看起來不錯的游客,加上可能一些內(nèi)容圖像下面。 您可能希望使標(biāo)頭跨越標(biāo)頭的整個寬度,并且內(nèi)容圖像適合內(nèi)容列中的某處。 讓我們來看一個簡單的例子:

這項功能適用于寬螢?zāi)谎b置,例如筆記本電腦或臺式機(jī)(您可以 -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.

雖然這還能看,但是當(dāng)你嘗試在一個狹小的屏幕設(shè)備上查看本頁面時,網(wǎng)頁的頭部看起來還可以,但是頭部這張圖片占據(jù)了屏幕的一大部分的高度,這真的很糟糕啊,而且這種情況下你僅僅只能看到人,旁邊的樹少了很多。

它會更好地顯示一個裁剪的版本的圖像,在重要的細(xì)節(jié)的鏡頭,當(dāng)網(wǎng)站被看到在一個窄屏幕上,可能是一個中等寬度的屏幕設(shè)備,如平板電腦之間的東西, 這通常被稱為藝術(shù)方向問題

此外,如果在微小的移動屏幕上觀看,則不需要在頁面上嵌入這樣大的圖像; 這被稱為分辨率切換問題 - 光柵圖像是設(shè)置的像素寬度和設(shè)置的像素數(shù)高; 正如我們在查看矢量圖形時所看到的,如果光柵圖像顯示為大于其原始大小,則光柵圖像開始看起來是顆粒和可怕的(而矢量圖形 沒有。)如果它顯示小于其原始大小,這是浪費(fèi)帶寬 - 移動用戶尤其不希望通過下載一個大型圖像打算用于桌面,通過他們的帶寬,當(dāng)一個小 圖像將為他們的設(shè)備。 理想的情況將是有多個分辨率可用,并根據(jù)訪問網(wǎng)站的不同設(shè)備提供適當(dāng)?shù)拇笮 ?/span>

為了使事情更復(fù)雜,一些設(shè)備具有高分辨率屏幕,需要更大的圖像,比你可能期望他們需要,以顯示得很好。 這本質(zhì)上是相同的問題,但在一個稍微不同的上下文。

你可能認(rèn)為矢量圖像將解決這些問題,他們在一定程度上做 - 他們在文件大小和規(guī)模都很小,你應(yīng)該盡可能使用它們。 它們不適合所有的圖像類型,雖然它們是偉大的簡單的圖形,圖案,界面元素等,它開始變得非常復(fù)雜,創(chuàng)建一個基于矢量的圖像與你會發(fā)現(xiàn) 在說,照片。 光柵圖像格式(如JPEG)更適合我們在上面示例中看到的圖像類型。

這種問題在網(wǎng)絡(luò)首次存在時并不存在,在90年代早期到中期 - 當(dāng)時唯一存在的設(shè)備是瀏覽網(wǎng)頁的是臺式機(jī)和筆記本電腦,所以瀏覽器工程師和規(guī)范作者甚至不想實現(xiàn) 解決方案。 最近實施了響應(yīng)圖像技術(shù),以解決上述問題,讓您向瀏覽器提供幾個圖像文件,它們都顯示相同的東西,但包含不同數(shù)量的像素( >),或適合于不同空間分配的不同圖像(藝術(shù)方向)。

注意:本文中討論的新功能 - srcset / 尺寸 / -CN / docs / Web / HTML /元素/圖片"> < picture> - 都支持現(xiàn)代桌面和移動瀏覽器的發(fā)布版本 IE瀏覽器。)

怎樣創(chuàng)建自適應(yīng)的圖片?

在本節(jié)中,我們將介紹上述兩個問題,并展示如何使用HTML的響應(yīng)式圖像功能解決這些問題。 您應(yīng)該注意到,我們將專注于HTML < img> 部分,如上例中的內(nèi)容區(qū)域所示 - 網(wǎng)站標(biāo)題中的圖片僅用于裝飾,因此使用CSS背景圖片實現(xiàn)。 CSS可能擁有更好的響應(yīng)式設(shè)計工具比HTML ,我們將在以后的CSS模塊中討論這些。

分辨率切換:不同尺寸

那么,我們想用分辨率切換解決什么問題? 我們想要顯示相同的圖片內(nèi)容,根據(jù)設(shè)備的不同,只是更大或更小 - 這是我們在示例中的第二個內(nèi)容圖片的情況。 < img> 標(biāo)準(zhǔn)傳統(tǒng)上只允許您將瀏覽器指向單個來源 文件:

<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 屬性看起來很復(fù)雜,但是如果你按照上面的方式對它們進(jìn)行格式化,每行的屬性值都有不同的部分 。 每個值包含逗號分隔的列表。 并且列表的每個部分由三個子部分組成。 讓我們現(xiàn)在運(yùn)行每個的內(nèi)容:

srcset 定義圖片集,我們將允許瀏覽器在每個圖片之間進(jìn)行選擇。 在每個逗號之前,

  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 定義一組媒體條件(例如屏幕寬度),并指示當(dāng)某些媒體條件為true時,最佳選擇什么圖片尺寸 - 這些是我們談?wù)摰奶崾?/span> 約早。 在這種情況下,在每個逗號之前我們寫

  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 )或相對長度(例如百分比)。 您可能已經(jīng)注意到,最后一個時隙寬度沒有媒體條件 - 這是在沒有媒體條件為真時選擇的默認(rèn)值。)瀏覽器忽略第一個匹配條件后的所有內(nèi)容,因此請小心如何排序媒體條件 。

所以,有了這些屬性,瀏覽器將:

  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 - 節(jié)省了65KB。 現(xiàn)在想象如果這是一個有很多圖片的頁面。 使用這種技術(shù)可以為移動用戶節(jié)省大量的帶寬。

不支持這些功能的舊版瀏覽器將忽略它們,并加載 "> src 屬性。

注意:在文檔的 < head> 您會發(fā)現(xiàn)< meta name ="viewport"content ="width = device-width"> :強(qiáng)制移動瀏覽器采用他們真正的視口寬度來加載網(wǎng)頁 瀏覽器關(guān)于它們的視口寬度,而是在更大的視口寬度加載頁面,然后收縮加載的頁面,這對響應(yīng)式圖像或設(shè)計不是非常有幫助,我們將在以后的模塊中教你更多)

一些有用的開發(fā)工具

瀏覽器中有一些有用的開發(fā)人員工具,可幫助您確定需要使用的必要插槽寬度等。 當(dāng)我開始工作時,我首先加載了我的示例的非響應(yīng)版本( not-responsive.html ),然后進(jìn)入 org / zh-CN / docs / Tools / Responsive_Design_Mode">響應(yīng)設(shè)計視圖(工具>網(wǎng)頁開發(fā)人員>響應(yīng)設(shè)計視圖),允許您查看網(wǎng)頁布局 好像他們正在通過各種不同的設(shè)備屏幕尺寸來觀看。

我設(shè)置視口寬度為320px然后480px; 對于我進(jìn)入 DOM檢查器的每個人,點擊了 -CN / docs / Web / HTML / Element / img"> < img> 元素,然后在右側(cè)的Box Model視圖選項卡中查看其大小 側(cè)的顯示。 這應(yīng)該給你所需的固有圖像寬度。

接下來,您可以通過將視口寬度設(shè)置為所需的寬度(例如將其設(shè)置為窄寬度)來檢查 srcset 是否正常工作,打開網(wǎng)絡(luò)檢查器( Tools> Web 開發(fā)人員>網(wǎng)絡(luò)),然后重新加載網(wǎng)頁。 這應(yīng)該給你一個下載的資產(chǎn)組成的網(wǎng)頁的列表,在這里你可以檢查選擇哪個圖像文件下載。

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

如果您支持多種顯示分辨率,但每個人都在屏幕上看到您的圖片在真實世界的大小,您可以允許瀏覽器使用 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應(yīng)用于圖像,以使其在屏幕上的寬度為320像素(也稱為CSS像素):

img {
  width: 320px;
}

在這種情況下,不需要 sizes - 瀏覽器簡單地計算出顯示的是什么分辨率,并且提供在 srcset 。 因此,如果訪問頁面的設(shè)備具有標(biāo)準(zhǔn)/低分辨率顯示,其中一個設(shè)備像素表示每個CSS像素,則將加載 elva-fairy-320w.jpg 圖像 您不需要包括它。)如果設(shè)備具有每個CSS像素或更高的兩個設(shè)備像素的高分辨率,將加載 elva-fairy-640w.jpg 圖像。 640px的圖片是93KB,而320px的圖片只有39KB。

藝術(shù)方向

總而言之,藝術(shù)方向問題包括想要更改顯示的圖像以適應(yīng)不同的圖像顯示尺寸。 例如,如果在桌面瀏覽器上查看時,如果在網(wǎng)站上顯示中間有人的大橫向鏡頭,則當(dāng)在移動瀏覽器上查看網(wǎng)站時縮小,則將看起來很糟糕,因為該人將是真的很小 很難看到。 最好在移動設(shè)備上顯示較小的肖像圖片,以顯示放大的人物。 < picture&gt ; 元素允許我們實現(xiàn)這種類型的解決方案。

返回我們原始的無響應(yīng) .html 示例,我們有一個非常需要藝術(shù)方向的圖片:

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

注意:您應(yīng)該僅在藝術(shù)方向場景中使用 media 屬性; 當(dāng)您確實使用 media 時,不要在 sizes 屬性中提供媒體條件。

為什么我們不能使用CSS或JavaScript?

當(dāng)瀏覽器開始加載頁面時,它會在主解析器開始加載和解釋頁面的CSS和JavaScript之前開始下載(預(yù)加載)任何圖像。 這是一個有用的技術(shù),平均來說,頁面加載時間減少了20%。 然而,它對響應(yīng)圖像沒有幫助,因此需要實現(xiàn)像 srcset 這樣的解決方案。 您無法加載 < img> 元素,然后檢測視口 寬度與JavaScript和動態(tài)地更改源圖像更小的,如果需要。 到那時,原始圖像已經(jīng)被加載,并且您將加載小圖像,這在響應(yīng)圖像術(shù)語中甚至更糟。

    大膽使用現(xiàn)代圖像格式

    有幾種令人興奮的新圖像格式(例如WebP和JPEG-2000)可以同時保持低文件大小和高質(zhì)量。 但是,瀏覽器支持是多斑點。

    < picture> 可讓我們繼續(xù)適應(yīng)舊版瀏覽器。 您可以在 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.

    主動學(xué)習(xí):實現(xiàn)您自己的響應(yīng)圖像

    對于這種積極的學(xué)習(xí),我們期待你勇敢,獨(dú)自去...大部分。 我們希望您使用< picture> 和使用 srcset 的分辨率切換示例來實現(xiàn)您自己的適合藝術(shù)的窄屏幕/寬屏幕鏡頭。

    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來幫助確定您需要的尺寸,如上所述。

    概要

    這是一個響應(yīng)圖像的包裝 - 我們希望你喜歡玩這些新技術(shù)。 作為一個總結(jié),有兩個不同的問題,我們在這里討論:

    • 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.

    這也將結(jié)束整個多媒體和嵌入模塊! 在繼續(xù)之前,現(xiàn)在唯一要做的就是嘗試我們的多媒體評估,看看你是怎么做的。 玩的開心。

    也可以看看

    以上內(nèi)容是否對您有幫助:
    在線筆記
    App下載
    App下載

    掃描二維碼

    下載編程獅App

    公眾號
    微信公眾號

    編程獅公眾號