HTML 文件圖片預設寬高比

Intrinsic aspect ratio of incomplete image

我在 2018 年有篇文章Intrinsic Size 媒體寬高比,介紹一個標準的草案intrinsicsize,為什麼會需要這東西在那篇文章也有講,主要就是要搭配像是:

img {
  max-width: 100%;
  height: auto;
}

這種寫法非常通用,但是在圖片讀取完成前,<img />標籤的佔位會無法先知道,這會造成頁面在圖片讀取完成後瀏覽器會需要比較大的重新繪製的工作。

這幾天想起來去查了一下近況,發現竟然早早就停止發展了,caniuse那邊也顯示瀏覽器都把一些實驗中的支援都拿掉了,細看下去,發現 Firefox 的人當時說要開始試驗另一個比較優雅的方法,也有和 CSS WG 的人開始討論,他們當時的想法就是直接用widthheight屬性來計算寬高比(aspect ratio),不過之後就都沒有標準文件相關的發展細節或連結了。

搜尋一番後,發現 Firefox 在 71 開始就已經發佈這個修改了,當時的release note其實有寫,而且 MDN 上還有一篇文章:Mapping the width and height attributes of media container elements to their aspect-ratio,也有介紹這個修改要解決的問題以及技術上是怎樣處理的,簡單一點形容就是:

img { 
  aspect-ratio: attr(width) / attr(height); 
}

不過實際上不是真的使用這條 User Agent style 來實作就是了,因為這個透過widthheight計算出來的寬高比只有在圖片還沒讀取的時候會有效,圖片讀取完成後就會改成用圖片實際的尺寸來計算怎麼顯示了,所以要說它是預設的寬高比也不太正確。

在 CSS Image 這個 Module 的第四章:Sizing Images and Objects in CSS中,有詳細的定義要怎樣決定圖片在繪製在網頁上時要怎樣處理,還定義了一些專有名詞:

  • Intrinsic dimensions 簡單一點形容就是圖片的原始尺寸,尺寸包含了寬(intrinsic width)、高和寬高比,不一定會全部都有,像是向量圖就只有寬高比,另外 intrinsic 中文翻譯是固有、或是根本的,所以 intrinsic dimentions 也不是真的就是圖片原始尺寸,它的文字敘述是:a preferred or natural size of the object itself。
  • Specified size 使用 CSS 設定的物件大小。
  • Concrete object size 根據上面兩個資訊所決定的實際上物件要繪製的大小,也就是我們眼睛所會看到的圖片呈現的大小。

所以主要就是在寫怎樣計算 concrete object size 了,大概計算過程就是和各位腦袋中想的不會差距太大。不過在這個地方,有一個細節是在 CSS 文件中故意沒有講出來的,就是怎樣取得 intrinsic dimensions,CSS 文件中沒有明確的說 intrinsic width 是來自圖片標籤的width屬性,或是圖片的實際寬度(早在 CSS 2.1 就有寫出CSS 文件不定義怎樣取得該數值了)。其實 HTML 圖片的 intrinsic dimensions 要怎麼取得是放在 HTML 文件的15.4.3,15 章都在講 rendering,15.4 則是 replaced elements,也就是圖片、影片之類的內容會整個替換掉的元素,15.4.3 最後一段的第一點是說圖片如果有抓下來的話就直接用圖片的 intrinsic aspect ratio,而第二點是這樣寫的:「If img'swidthandheightattribute values, when parsed using the rules for parsing dimension values), are both not an error, not a percentage, and non-zero, then use the ratio resulting from dividing thewidthattribute value by theheightattribute value.」這邊就明確的寫到用兩個屬性來計算 intrinsic aspect ratio 了,不過針對這個圖片讀取完成前的 intrinsic aspect ratio,並沒有定義一個專有名詞,所以可以看到 cnaiuse 用一個複雜的文字來敘述這項修改,要是我的話應該會把這個值命名為 intrinsic aspect ratio of incomplete image 之類的吧。

最後整理一下:

  • 圖片讀取完成前,如果有設定正確的數值的 width 和 hieght 的話,瀏覽器會先它們來計算 intrinsic aspect ratio
  • 圖片讀取完成後,瀏覽器會用圖片原始的寬高比來作為 intrinsic aspect ratio
  • 本來是希望能用在所有的 replaced elements,不過會造成既有網站壞掉所以目前限制在<img>標籤
  • 以上的修改是大約是今年前半年才進入瀏覽器的

Scroll Margin/Padding

這篇文章要介紹一組算是蠻新的 CSS 屬性,分別是scroll-marginscroll-padding,這兩個屬性是在Scroll Snap Module Level 1裡面定義的,目前主要的瀏覽器都有支援,IE 完全不支援,Safari 則是還在使用舊的非標準的屬性名稱,為什麼要介紹這兩個屬性呢?因為它除了原來 scroll-snap 微調的需求之外,還順便解決了一個存在已久的問題,也就是如果網頁的設計有固定浮動在頁面頂端的 header 時(Sticky/Fixed Header),使用 link 的 fragment 直接定位到頁面特定位置的時候,最上面一部份想顯示給訪客的內容會被 header 覆蓋到。

這個問題大概是從 Sticky Header 出現時就存在了,Stack Overflow 上就可以找到十年前的發問,以前的主要的解決方法就是讓連結的目標有看不到的高度,像是用padding-top,比較乾淨一點是用 pseudo-element 的:before來把內容往下推,不過這幾個方法雖然有用,但是對我來說卻一直不是個最佳解,所以一直以來我都期待能有更漂亮的解決方案,有事沒事就會搜尋一下,然後,終於我發現了這組 CSS 屬性可以用來讓瀏覽器自己捲動到目標時有指定的偏移。

scroll-margin是用在你想要捲動到的目標元件上,也就是有 id 的那個,像我的 blog 就是<article>標籤,給它加個scroll-margin-top: 56px;就可以了:

article {
  scroll-margin-top: 56px;
}

scroll-padding則是要用在scroll container上的,而不是目標的父母層,舉例來說,在我這邊,沒有特別設定任何overflow的情形下,scroll container 會落在<html>元件上,而不是<article>外面的<main>,所以設定就要改成:

html {
  scroll-padding-top: 56px;
}

這組 CSS 屬性我是今年才發現的,不過其實 CSS Trick 在去年就有文章介紹了:Fixed Headers, On-Page Links, and Overlapping Content, Oh My!,真是太後知後覺了(其實也是因為我現在沒用 RSS reader 的關係)。



USB-C、DisplayPort

LG UltraFine 5K

前陣子為了買螢幕認真的研究了一下 USB-C 介面的問題,然後就在 FB 上快速的紀錄了一下,這篇就把那時的紀錄轉過來,每段文字前後有點不連貫還請忽略,然後尾巴加一些後來研究才知道的東西,當然因為我不是這方面專業的,內容有錯還請通知我~

最有趣的大概是 USB-C to HDMI 幾乎都是走 DisplayPort Alt. mode 然後線上晶片轉成 HDMI 訊號吧,反而沒有什麼支援輸出 HDMI Alt. mode 的設備,就算有,用上這種主動線材也不能用,然後買線的時候,有些廠商又不寫他是支援 DisplayPort Alt. mode 還是 HDMI Alt. mode(像是那個 moshi,盒子上可能有寫但是網站上都沒寫),不過現在應該幾乎都是前者吧,後者專用的線材可能還要特別去找。

然後 Mac 之前 Thunderbolt 3 其實只有支援到傳輸 DisplayPort 1.2 的訊號,但是 DisplayPort 1.2 的資料傳輸量只有支援到 4K 60Hz,只是 Thunderbolt 3 可以傳輸兩組 DisplayPort 1.2 訊號,所以可以把 5K 60Hz 10bpc(bit per color) 的視訊資料塞進去。不過最近出的 Pro Display XDR 是 6K 螢幕,一樣只用一條 Thunderbolt 3 線傳輸,研究一番才發現應該是 Mac 換了新的 Thunderbolt 晶片,現在支援到 DisplayPort 1.4,所以可以輸出到 6K 訊號了,不過一般查 Thunderbolt 3 都還是只有寫支援到 DisplayPort 1.2,不知道是不是其實這部分是動態沒寫死的。

再來就是我之前貼的兩台螢幕,MSI 那台的 USB-C 頭在使用手冊內有寫說不支援數據傳輸,所以那個頭應該是用 USB-C 的 DisplayPort Alt. mode,而不是 Thunderbolt Alt. mode 去傳輸 DisplayPort 訊號,LG 的是後者,所以它可以一條線同時做訊號傳輸,還提供筆電充電和三個 USB-C 頭出來(真的是 USB 介面的),不過沒有 downstream 來串接 Thunderbolt 設備,4K 版才有多餘的頻寬。

蘋果那條 Pro Cable 厲害的點就是在它有 2M 長度,但是:

  1. 支援 USB-C 資料傳輸,傳輸速度可以到 USB 3.1 Gen 2 的 10Gbps;
  2. Thunderbolt 3 Alt. mode,傳輸速度可以到最高速的 40 Gbps;
  3. DisplayPort Alt. mode 訊號,並且支援到 1.3 的 HBR3,資料量有到 25.92 Gbps;
  4. 支援充電到 100W,也是 Thunderbolt 3 規格的最高功率。

可以說是目前最常見的模式都有支援到目前的頂級規格了,一般這種長度的線通常就是:1. 普通 USB-C 被動(沒晶片處理)線材,然後就無法乘載 Thunderbolt 3 的 40G 訊號;2. 主動的 Thunderbolt 3 or DisplayPort 線材,但是就會變成只能傳輸自己支援的訊號,不能當 USB-C 線用,蘋果那條線到底是怎麼同時達成其實還不清楚,充電要怎樣能到 100W 然後同時傳輸這樣大量的資料也是很厲害。其實也有廠商出過同時可以當 Thunderbolt 3 和 USB 的線材,只是 USB 就不能到 10Gbps,充電也有差,總之就是沒有樣樣完美的。

MacBook Pro 16 現在有支援同時輸出給兩台 Pro Display XDR,不過要一台插左邊,一台插右邊,其實 5K 就需要了,官網文件有寫,所以大概可以知道四個 port 頻寬是左右兩邊分開的,其實 Apple 官方文件寫的還蠻仔細的,不同機種都有各自的文件說明:

然後 DisplayPort 1.4 有支援到 8K 60Hz 的訊號,Dell 也有一台 8K 螢幕 UP3218K 支援到 8K 60Hz 10bpc,不過現在一來 macOS 不支援輸出 8K,二來 Dell 那台如果要支援 8K 60Hz 是用兩條 DisplayPort 1.3(標準接頭)來傳輸訊號的,因為 DisplayPort 1.3 只有支援到 8K 30Hz,單一條無法到達 60Hz。不過一來 30Hz 蘋果不喜歡,二來兩條線也不符合蘋果美學,所以這個組合在可見的未來大概也是無法搭配在一起吧,我推測蘋果的裝置要支援到 8K 螢幕應該是至少要先換到 Thunderbolt 4 的介面,用比較高效的編碼然後用到單向 80Gbps 的傳輸,不過單向傳輸的話其實就無法同時串接 Thunderbolt 裝置了,也會變成無法達成一條線同時傳視訊、資料和充電,到時候到底會怎樣還是很很讓人好奇啊。

說到這其實我就很好奇,兩條 DisplayPort 線輸出高解析度畫面,這靠的是什麼標準呢?以前在 DVI 時代,這叫做 Dual-Link,不過 DisplayPort 似乎沒有相對應的專有名詞,蘋果網站和 LG 說是 dual-link SST(Single Stream Transport) ,Thunderbolt 網站有看到寫 Dual DisplayPort 的,不過似乎都不是正式的名稱,我基於好奇搜尋許久,還找到看起來好像很有關連的 DisplayPort Dual Mode(DP++)這東西,但是其實這也不是我要找的,我要找的最後是在一份 VESA 在 Display Summit 用的投影片中找到,這份投影片叫:DisplayPort Future Proofing Display Connectivity for VR and 8K HDR,其實這個能力是真的沒有特別的專有名詞(行銷用詞),它是利用DisplayID的一個功能「Tiled Display Topology Data Block」來達成的,意思就是顯示器的 DisplayID 會跟訊源說你可以把我當成是一組並排螢幕中的一個,Dell UP3218K 是需要實體的 DisplayPort 線兩條,顯示器只要其中一個孔位說是左邊,一個說是右邊就可以,然後解析度都是 3840 × 4320 at 60Hz ,像 Thunderbolt 3 可以傳輸兩組 DisplayPort 訊號,也是一樣的方式,接 UltraFine 5K 的話是兩組 2560 × 2880 at 60Hz 10bpc 的訊號。

Pro Cable

最後,如果你看到一台螢幕號稱說是 USB-C 螢幕,那有三種可能性,一是它只支援 Thunderbolt Alt. mode,像是舊版的 LG UltraFine 5K;二是它只支援 DisplayPort Alt. mode,像是 MSI Prestige PS341WU;最後就是兩種都支援,像是新版的 LG UltraFine 5K。哇!除了線材挑選有學問之外,螢幕說支援 USB-C 接頭傳輸視訊,其實也有不同可能性了,USB-C 真的很難!



➡ 看看其它文章