自適應設計:自適應圖片的完整教程
時間:2023-08-28 20:24:01 | 來源:網(wǎng)站運營
時間:2023-08-28 20:24:01 來源:網(wǎng)站運營
自適應設計:自適應圖片的完整教程:
在這篇文章中我們將學習關于自適應圖片:一種可以在不同的屏幕尺寸和分辨率的設備上都能良好工作以及其他特性的圖片,并且看看HTML提供了什么工具來幫助實現(xiàn)它們。自適應圖片僅僅只是自適應
網(wǎng)站設計的一部分,為您奠定了自適應網(wǎng)頁設計的良好基礎。
為什么要用自適應的圖片?
讓我們來看一個典型的場景。一個典型的網(wǎng)站可能會有一張頁首圖片,這讓訪問者看起來感到愉快。圖片下面可能會添加一些內容圖像。頁首圖像的跨度可能是整個頁首的寬度。而內容圖像會適應內容縱列的某處。此處有個簡單的例子:
這個網(wǎng)頁在寬屏設備上表現(xiàn)良好,例如筆記本電腦或臺式機(你可以查看在線演示并且在GitHub上查看
源代碼)。我們不會在這一節(jié)課中討論CSS,除了下面提到的那些:
- 正文內容被設置的最大寬度為1200像素——在高于該寬度的可視窗口中,正文保持在1200像素,并將其本身置于可用空間的中間。在該寬度以下的可視窗口中,正文將保持在可視窗口寬度的100%。
- 頁眉圖像被設置為使其中心始終位于頁眉的中心,無論頁眉的寬度是多少。所以如果網(wǎng)站被顯示在窄屏上,圖片中心的重要細節(jié)(里面的人)仍然可以看到,而兩邊超出的部分都消失了。它的高度是200px。
- 內容圖片已經(jīng)被設置為如果body元素比圖像更小,圖像就開始縮小,這樣圖像總是在正文里,而不是溢出正文。
然而,當你嘗試在一個狹小的屏幕設備上查看本頁面時,問題就會產(chǎn)生。網(wǎng)頁的頁眉看起來還可以,但是頁眉這張圖片占據(jù)了屏幕的一大部分的高度,在這個尺寸下,你很難看到在第一張圖片內容里的人。
一個改進的方法是,當網(wǎng)站在狹窄的屏幕上觀看時,顯示一幅圖片的包含了重要細節(jié)的裁剪版本,第二個被裁剪的圖片會在像平板電腦這樣的中等寬度的屏幕設備上顯示,這就是眾所周知的
美術設計問題(art direction problem)。
另外,如果是在小屏手機屏幕上顯示網(wǎng)頁,那么沒有必要在網(wǎng)頁上嵌入這樣大的圖片。這被稱之為
分辨率切換問題(resolution switching problem)。位圖有固定數(shù)量的像素寬,固定數(shù)量的像素高,與矢量圖外觀相同,但本質不同。如果顯示尺寸大于原始尺寸,一張自身較小的位圖看起來會有顆粒感(矢量圖則不會)。
相反,沒有必要在比圖片實際尺寸小的屏幕上顯示一張大圖,這樣做會浪費帶寬——當可以在設備上使用小圖像時,手機用戶尤其不愿意因為下載用于桌面的大圖像而浪費帶寬。理想的情況是當訪問網(wǎng)站時依靠不同的設備來提供不同的分辨率圖片和不同尺寸的圖片。
讓事情變得復雜的是,有些設備有很高的分辨率,為了顯示的更出色,可能需要超出你預料的更大的圖像。這從本質上是一樣的問題,但在環(huán)境上有一些不同。
你可能會認為矢量圖形能解決這些問題,在某種程度上是這樣的——它們無論是文件大小還是比例都合適,無論在哪里你都應該盡可能的使用它們。然而,它們并不適合所有的圖片類型,雖然在簡單圖形、圖案、界面元素等方面較好,但如果是有大量的細節(jié)的照片,創(chuàng)建矢量圖像會變得非常復雜。像JPEG格式這樣的位圖會更適合上面例子中的圖像。
當web第一次出現(xiàn)時,這樣的問題并不存在,在上世紀90年代中期,僅僅可以通過筆記本電腦和臺式機來瀏覽web頁面,所以瀏覽器開發(fā)者和規(guī)范制定者甚至沒有想到要實現(xiàn)這種解決方式(響應式開發(fā))。最近應用的響應式圖像技術,通過讓瀏覽器提供多個圖像文件來解決上述問題,比如使用相同顯示效果的圖片但包含多個不同的分辨率(分辨率切換),或者使用不同的圖片以適應不同的空間分配(美術設計)。
注意: 在這篇文章中討論的新特性 — srcset/sizes/<picture> — 都已經(jīng)被新版本的現(xiàn)代瀏覽器和移動瀏覽器所支持(包括Edge,而不是IE)。
怎樣創(chuàng)建自適應的圖片?
在這一部分中,我們將看看上面說明的兩個問題,并且展示怎樣用HTML的響應式圖片來解決這些問題。需要注意的是,如以上示例所示,在本節(jié)中我們將專注于HTML的 <img>,但網(wǎng)站頁眉的圖片僅是裝飾性的,實際上應該要用CSS的背景圖片來實現(xiàn)。CSS是比HTML更好的響應式設計的工具,我們會在未來的CSS模塊中討論。
分辨率切換:不同的尺寸
那么,我們想要用分辨率切換解決什么問題呢?我們想要顯示相同的圖片內容,僅僅依據(jù)設備來顯示更大或更小的圖片——這是我們在示例中使用第二個內容圖像的情況。標準的<img>元素傳統(tǒng)上僅僅讓你給瀏覽器指定唯一的資源文件。
<img src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
我們可以使用兩個新的屬性——srcset 和 sizes——來提供更多額外的資源圖像和提示,幫助瀏覽器選擇正確的一個資源。你可以看到 responsive.html 的例子,也可以在GitHub上看到
源碼:
<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">
srcset和sizes屬性看起來很復雜,但是如果你按照上圖所示進行格式化,那么他們并不是很難理解,每一行有不同的屬性值。每個值都包含逗號分隔的列表。列表的每一部分由三個子部分組成。讓我們來看看現(xiàn)在的每一個內容:
srcset定義了我們允許瀏覽器選擇的圖像集,以及每個圖像的大小。在每個逗號之前,我們寫:
- 一個文件名 (elva-fairy-480w.jpg.)
- 一個空格
- 圖像的固有寬度(以像素為單位)(480w)——注意到這里使用w單位,而不是你預計的px。這是圖像的真實大小,可以通過檢查你電腦上的圖片文件找到(例如,在Mac上,你可以在Finder上選擇這個圖像,然后按 Cmd + I 來顯示信息)。
sizes定義了一組媒體條件(例如屏幕寬度)并且指明當某些媒體條件為真時,什么樣的圖片尺寸是最佳選擇—我們在之前已經(jīng)討論了一些提示。在這種情況下,在每個逗號之前,我們寫:
- 一個媒體條件((max-width:480px))——你會在 CSS topic中學到更多的。但是現(xiàn)在我們僅僅討論的是媒體條件描述了屏幕可能處于的狀態(tài)。在這里,我們說“當可視窗口的寬度是480像素或更少”。
- 一個空格
- 當媒體條件為真時,圖像將填充的槽的寬度(440px)
注意: 對于槽的寬度,你也許會提供一個固定值 (px, em) 或者是一個相對于視口的長度(vw),但不是百分比。你也許已經(jīng)注意到最后一個槽的寬度是沒有媒體條件的,它是默認的,當沒有任何一個媒體條件為真時,它就會生效。 當瀏覽器成功匹配第一個媒體條件的時候,剩下所有的東西都會被忽略,所以要注意媒體條件的順序。
所以,有了這些屬性,瀏覽器會:
- 查看設備寬度
- 檢查sizes列表中哪個媒體條件是第一個為真
- 查看給予該媒體查詢的槽大小
- 加載srcset列表中引用的最接近所選的槽大小的圖像
就是這樣!所以在這里,如果支持瀏覽器以視窗寬度為480px來加載頁面,那么(max-width: 480px)的媒體條件為真,因此440px的槽會被選擇,所以elva-fairy-480w.jpg將加載,因為它的的固定寬度(480w)最接近于440px。800px的照片大小為128KB而480px版本僅有63KB大小—節(jié)省了65KB?,F(xiàn)在想象一下,如果這是一個有很多圖片的頁面。使用這種技術會節(jié)省移動端用戶的大量帶寬。
老舊的瀏覽器不支持這些特性,它會忽略這些特征。并繼續(xù)正常加載 src屬性引用的圖像文件。
注意: 在 HTML 文件中的 <head> 標簽里, 你將會找到這一行代碼 <meta name="viewport" content="width=device-width">: 這行代碼會強制地讓手機瀏覽器采用它們真實可視窗口的寬度來加載網(wǎng)頁(有些手機瀏覽器會提供不真實的可視窗口寬度, 然后加載比瀏覽器真實可視窗口的寬度大的寬度的網(wǎng)頁,然后再縮小加載的頁面,這樣的做法對響應式圖片或其他設計,沒有任何幫助。我們會在未來的模塊教給你更多關于這方面的知識)。
一些有用的開發(fā)工具
這里有一些在瀏覽器中的非常實用的
開發(fā)者工具用來幫助制定重要的槽寬度,以及其他你可能會用到的場景。當我在設置槽寬度的時候,我先加載了示例中的無響應的版本(not-responsive.html),然后進入響應設計視圖 (
Tools > Web Developer > Responsive Design View),這個工具允許你在不同設備的屏幕寬度場景下查看網(wǎng)頁的布局。
我設置我的視圖寬度為 320px,然后再改為 480px;每一次寬度的改變我就進入DOM 檢查 ,點擊我們感興趣的 <img> 元素,然后在顯示屏右側的 Box Model 視圖選項卡中查看它的大小。 你應該會看到,這種無響應式的做法會讓你的圖片在不同屏幕寬度下有著固定的寬度。
接著, 你可以檢查 srcset 是否正常工作,你需要將視圖的寬度設置為你想要的,(比如,把寬度設置的比較小,讓頁面看起來比較狹窄),打開網(wǎng)絡檢查(
Tools > Web Developer > Network),然后重新加載頁面。網(wǎng)絡檢查工具會給你一個列表,里面的文件都是已經(jīng)被下載來構造網(wǎng)頁的。然后你可以在這里看到哪個圖像文件被下載了。
注意: 在 Chrome 中測試時,通過如下方式禁用緩存:打開 DevTools ,并選中 Settings > preferences > Network下Disable cache的選擇框。否則,Chrome 會優(yōu)先選擇緩存圖片而不是恰好適配的那個。
分辨率切換: 相同的尺寸, 不同的分辨率
如果你支持多種分辨率顯示,但希望每個人在屏幕上看到的圖片的實際尺寸是相同的,你可以讓瀏覽器通過srcset和x語法結合——一種更簡單的語法——而不用sizes,來選擇適當分辨率的圖片。你可以看一個例子
srcset-resolutions.html:
<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">
在這個例子中,下面的CSS會應用在圖片上,所以它的寬度在屏幕上是320像素(也稱作CSS像素):
img { width: 320px; }
在這種情況下,sizes并不需要——瀏覽器只是計算出正在顯示的顯示器的分辨率,然后提供srcset引用的最適合的圖像。因此,如果訪問頁面的設備具有標準/低分辨率顯示,一個設備像素表示一個CSS像素,elva-fairy-320w.jpg會被加載(1x 是默認值,所以你不需要寫出來)。如果設備有高分辨率,兩個或更多的設備像素表示一個CSS像素,elva-fairy-640w.jpg 會被加載。640px的圖像大小為93KB,320px的圖像的大小僅僅有39KB。
美術設計
回顧一下,
美術設計問題涉及要更改顯示的圖像以適應不同的圖像顯示尺寸。例如,如果在桌面瀏覽器上的一個網(wǎng)站上顯示一張大的、橫向的照片,照片中央有個人,然后當在移動端瀏覽器上瀏覽這個網(wǎng)站時,照片會縮小,這時照片上的人會變得非常小,看起來會很糟糕。這種情況可能在移動端顯示一個更小的肖像圖會更好,這樣人物的大小看起來更合適。<picture>元素允許我們這樣實現(xiàn)。
回到我們最初的例子
not-responsive.html ,我們有一張圖片需要美術設計:
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
讓我們改用 <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" alt="Chris standing up holding his daughter Elva"> </picture>
- <source>元素包含一個media屬性,這一屬性包含一個媒體條件——就像第一個srcset例子,這些條件來決定哪張圖片會顯示——第一個條件返回真,那么就會顯示這張圖片。在這種情況下,如果視窗的寬度為799px或更少,第一個<source>元素的圖片就會顯示。如果視窗的寬度是800px或更大,就顯示第二張圖片。
- srcset屬性包含要顯示圖片的路徑。請注意,正如我們在<img>上面看到的那樣,<source>可以使用引用多個圖像的srcset屬性,還有sizes屬性。所以你可以通過一個 <picture>元素提供多個圖片,不過也可以給每個圖片提供多分辨率的圖片。實際上,你可能不想經(jīng)常做這樣的事情。
- 在任何情況下,你都必須在 </picture>之前正確提供一個<img>元素以及它的src和alt屬性,否則不會有圖片顯示。當媒體條件都不返回真的時候(你可以在這個例子中刪除第二個<source> 元素),它會提供圖片;如果瀏覽器不支持 <picture>元素時,它可以作為后備方案。
這樣的代碼允許我們在寬屏和窄屏上都能顯示合適的圖片,像下面展示的一樣:
注意: 你應該僅僅當在美術設計場景下使用media屬性;當你使用media時,不要在sizes屬性中也提供媒體條件。
為什么我們不能使用 CSS 或 JavaScript 來做到這一效果?
當瀏覽器開始加載一個頁面, 它會在主解析器開始加載和解析頁面的 CSS 和 JavaScript 之前先下載 (預加載) 任意的圖片。這是一個非常有用的技巧,平均下來減少了頁面加載時間的20%。但是, 這對響應式圖片一點幫助都沒有, 所以需要類似 srcset的實現(xiàn)方法。因為你不能先加載好 <img> 元素后, 再用 JavaScript 檢測可視窗口的寬度,如果覺得大小不合適,再動態(tài)地加載小的圖片替換已經(jīng)加載好的圖片,這樣的話, 原始的圖像已經(jīng)被加載了, 然后你又加載了小的圖像, 這樣的做法對于響應式圖像的理念來說,是很糟糕的。
大膽的使用現(xiàn)代圖像格式
有很多令人激動的新圖像格式(例如WebP和JPEG-2000)可以在有高質量的同時有較低的文件大小。然而,瀏覽器對其的支持參差不齊。
<picture>讓我們能繼續(xù)滿足老式瀏覽器的需要。你可以在type屬性中提供MIME類型,這樣瀏覽器就能立即拒絕其不支持的文件類型:
<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>
- 不要使用media屬性,除非你也需要美術設計。
- 在<source> 元素中,你只可以引用在type中聲明的文件類型。
- 像之前一樣,如果必要,你可以在srcset和sizes中使用逗號分割的列表。
主動學習:實現(xiàn)屬于你的響應式圖像
在這次主動學習中,我們希望你變得勇敢和自力更生……盡量的。我們希望你通過使用<picture>來實現(xiàn)自己美術設計上的寬/窄屏顯示適配,以及使用 srcset切換不同的分辨率。
- 寫一些簡單 HTML 來包含你的代碼(如果你喜歡,也可以使用 not-responsive.html 作為起點)。
- 找一張漂亮的寬屏風景圖像,其中需要包含一些細節(jié)。使用圖像編輯器創(chuàng)建一個網(wǎng)頁大小的版本。然后裁剪一下,顯示一個更小的部分,其中包含放大的細節(jié), 然后創(chuàng)建第二張圖片 (差不多 480px 寬度比較好。)
- 使用 <picture> 元素來實現(xiàn)藝術圖片切換器!
- 創(chuàng)建不同大小的多張圖片, 每個圖片的圖像都是一樣的。
- 使用 srcset/size 來創(chuàng)建一個分辨率切換器示例, 可以在不同的分辨率的情況下,提供相同尺寸的圖像, 或者在不同的視圖大小的情況下,提供不同尺寸大小的圖像。
注意: 使用瀏覽器開發(fā)工具來幫助你工作時可以得到你需要的視圖大小,就像上文提到的。
總結
這章節(jié)中充滿了響應式圖像 — 我們希望你學習新技術的過程是享受的。概括來說,有兩個不同的問題,文章中我們一直在討論:
- 美術設計:當你想為不同布局提供不同剪裁的圖片——比如在桌面布局上顯示完整的、橫向圖片,而在手機布局上顯示一張剪裁過的、突出重點的縱向圖片,可以用 <picture> 元素來實現(xiàn)。
- 分辨率切換:當你想要為窄屏提供更小的圖片時,因為小屏幕不需要像桌面端顯示那么大的圖片;以及你想為高/低分辨率屏幕提供不同分辨率的圖片時,都可以通過 vector graphics (SVG images)、 srcset 以及 sizes 屬性來實現(xiàn)。