Responsive images == ###### tags: `CSS` Udemy :Advanced CSS and Sass: Flexbox, Grid, Animations and More 課程筆記 ## <font color="#3733FF">什麼是Responsive images</font> 目的是將正確的圖像提供給正確的屏幕尺寸和設備,依據使用者目前的螢幕大小來顯示合適的圖片大小,以避免在較小的螢幕上下載不必要的大圖像。 譬如說網頁封面圖片在電腦上呈現的圖片大小是1MB,我們不會希望使用者用手機瀏覽網站時也需要下載1MB 但設計者也需要準備不同大小的圖片 通常有三個方式 1. Resolution Switching(解析度切換) 2. Density Switching(密度切換): 根據目前螢幕的分辨率高低提供同一圖片的較大或較小版本,可以在`<img>`或`<soucrce>`元素中使用` srcset`屬性 3. Art Direction(藝術風格指導): 使用`<picture>`元素 ### <font color="#3733FF">Density Switching</font> 譬如我在footer有一個logo,寬度是10rem,我們先放一個兩倍大的圖片 ```htmlembedded! <img src="./img/logo-green-2x.png" alt="Full logo" class="footer__logo"> ``` 這時候觀察console,兩倍大的圖片寬度在螢幕上顯示的寬度大概是兩倍 ![](https://hackmd.io/_uploads/H1YuXxsD2.png) 那如果我希望在低分辨率的螢幕顯示一倍大的圖片就好 html可以改成這樣,使用srcset屬性,提供兩個圖片連結並註明density description 是1x 和2x ```htmlembedded! <img srcset="./img/logo-green-1x.png 1x, ./img/logo-green-2x.png 2x" alt="Full logo"> ``` 這樣瀏覽器會根據使用者的顯示網頁的螢幕,從兩個選最好的一個 譬如我在macbook air上測試,出現2x ![](https://hackmd.io/_uploads/ByuxLxjDh.png) 在外接螢幕上測試,出現1X ![](https://hackmd.io/_uploads/SJ_eUgjPh.png) ### <font color="#3733FF">Art Direction</font> 透過設定不同螢幕大小,決定要顯示什麼圖片,使用`<picture>`元素 一樣都提供兩個不同圖片大小的檔案,在`<source>`中,使用media屬性將我們定義的螢幕寬度放進去,記得要加括號,我們指定在螢幕小於37.5em,也就是小於600px時,換成另一張小圖片 某程度來說是強制瀏覽器使用在這裡定義的圖片,避免使用css 的media query ```htmlembedded! <picture class="footer__logo"> <source srcset="./img/logo-green-small-1x.png 1x, ./img/logo-green-small-2x.png 2x" media="(max-width:37.5em)"> <img srcset="./img/logo-green-1x.png 1x, ./img/logo-green-2x.png 2x"> </picture> ``` ![](https://hackmd.io/_uploads/rko-Oxsw2.gif) ### <font color="#3733FF">Resolution Switching</font> 也一起處理Density Switching 瀏覽器在加載HTML時,會知道目前視窗的寬度,也知道目前螢幕的pixel density,就可以判斷要使用哪一個的大小的圖片 1. 直接在瀏覽器定義兩張圖片的實際寬度,這次不用1x. 或2x,使用width description ```htmlembedded! <!-- 讓瀏覽器根據目前的屎窗寬度和pixel density來選擇最佳的圖片 --> <img srcset="./img/nat-1.jpg 300w, ./img/nat-1-large.jpg 1000w"> ``` 2. 加上sizes的屬性定義大小,來通知瀏覽器在不同的視窗的寬度下,圖片大概的寬度,讓它知道要載入哪張圖片(加上前面已經提供width description和螢幕的分辨率) > sizes 屬性用於定義圖片在不同視窗大小下的顯示尺寸。這個屬性使用了一個帶有媒體查詢(media query)的列表,,以及對應的尺寸值,媒體查詢是一種在 CSS 中使用的條件語句,用於根據裝置的特性(如視窗寬度)來應用不同的樣式或設置。 從900px 的視窗開始定義,如果是900px時,圖片寬度是視窗寬度的20%,600px時也差不多,最後的300px是當視窗寬度大於 900px時,圖片的寬度將固定為 300px。 ```htmlembedded! <!-- 讓瀏覽器根據目前的屎窗寬度和pixel density來選擇最佳的圖片 --> <img srcset="./img/nat-1.jpg 300w, ./img/nat-1-large.jpg 1000w" sizes="(max-width:900px) 20vw, (max-width: 600px) 30vw, 300px" alt="photo 1" src="./img/nat-1-large.jpg" class="composition__photo composition__photo--p1"> ``` ![](https://hackmd.io/_uploads/HyZCcXsw3.png) ### 在CSS中實作responsive images 我們嘗試調整封面照片,透過min-resolution 最小分辨率和最小寬度要大於600px的條件來載入不同大小的照片 ` @media (min-resolution: 192dpi) and (min-width: 600px){}` 以apple的電腦當例子,每英吋192點,這是高分辨率的螢幕 ```sass .header { position: relative; height: 95vh; background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url('../img/hero-small.jpg'); @media (min-resolution: 192dpi) and (min-width: 600px) { background-image: linear-gradient(to right bottom, rgba($color-primary-light, 0.8), rgba($color-primary-dark, 0.8)), url('../img/hero.jpg'); } ``` 可以觀察到從螢幕小於600px拉到超出600px,對應的圖片就從hero-small變成hero了 ![](https://hackmd.io/_uploads/HkpbNViPh.gif) 如果我們希望當螢幕寬度是2000px時,也可以套用的話,可以修改一下media,加一個逗號,代表 or 要注意的是,也要檢查瀏覽器有沒有支援像`min-resolution: 192dpi`的寫法,可以先將兩個圖片套用不能的漸層色,目視觀察有沒有變化 ```sass! @media (min-resolution: 192dpi) and (min-width: 600px), (min-width: 2000px) { background-image: linear-gradient(to right bottom, rgba($color-secondary-light, 0.8), rgba($color-secondary, 0.8)), url('../img/hero.jpg'); } ``` 譬如我觀察到,在chrome、firefox、safari中只有safari載入時是`$color-primary-light`綠色的 ![](https://hackmd.io/_uploads/S1eflBiv2.png) ![](https://hackmd.io/_uploads/SylxzgHswh.png) safari不支援`min-resolution: 192dpi`,只用`-webkit-min-device-pixel-ratio: 2`代替 ```sass! @media (min-resolution: 192dpi) and (min-width: 37.5em), (-webkit-min-device-pixel-ratio: 2) and (min-width: 37.5em), (min-width: 125em) { background-image: linear-gradient(to right bottom, rgba($color-secondary-light, 0.8), rgba($color-secondary-dark, 0.8)), url('../img/hero.jpg'); } ``` ---