html2canvas & The color Function Within the :disabled Pseudo-Class
color function is not supported
最近有一個需求要將當前畫面儲存成圖片下載。於是我找到 html2canvas 這個將畫面 html 內容繪製成 canvas 內容的套件。
整合過程很順利,我一路過關斬將從 Firefox, Chrome,然後到 iPhone 裡頭的 Safari。但就在我從手機裡頭儲存圖片卻失靈了。礙於 iPhone 裡頭 Safari 不容易除錯,我改從 Macos 的 Safari 測試。結果一樣發生錯誤。並且 Console 顯示了下列錯誤:
Unhandled Promise Rejection:
Error:
Attempting to parse an unsupported color function "color"
透過追蹤代碼,我知道 html2canvas 會在渲染的時候檢查相關的 css 屬性。其中 color function
無法被正確渲染。所以回頭檢查 html 代碼,確定沒有使用 color 的部分。但為何錯誤會發生在我的某個 html 元素有使用 color?
:disabled Pseudo-Class
為了盡快釐清問題,我開始將部分的 html 移除,試著縮小範圍。而當我將畫面上的表單內容移除之後,功能居然正常了!為何?
更進一步,我將表單留到只剩下一個 input 元素
<input name="phone" type="text" inputmode="numeric"
pattern="\d{11}"
oninput="this.value=this.value.replace(/[^0-9]/g,'')" disabled=""
placeholder="請輸入手機"
minlength="11"
maxlength="11" />
由於這個元素有多個屬性使用,我逐步地刪除,直到發現把 disabled=""
移除之後功能正常了。但是,這又是為何?
由於為了避免 CSS 預設瀏覽器差異,我在最上頭使用 reset.css 重新設定 css 樣式。按理瀏覽器彼此的差異應該所剩無幾,很快地想到預設的 :disabled
可能使用了 color function 定義顏色。於是我找到 What color do disabled text-boxes in html uses? 確認了我的疑慮。
然後透過瀏覽器確認預設 input:disabled
樣式是:
input:disabled, textarea:disabled {
color: color(srgb 0.34 0.34 0.34);
}
於是我自定義了一組 css 樣式覆蓋原本的樣式:
input:disabled {
color: #C6C6C6;
}
重新執行一次之後 Safari 正常了。接著在手機上的 Safari 也順利成功。
看不見的細節
這個問題,一開始認為是套件的問題。可能對 Safari 的支持不佳,於是開啟官方網站,用官網的 capture 功能擷取畫面,結果沒問題。
轉而檢查自己的 html 內容。在找不到線索的時候,才透過刪去法限縮範圍,想不到最後會在一個 disabled
屬性上發現問題。
若不是該 input 元素預設即為 disabled
,如果是在動態切換的過程設定 disabled
。恐怕這次除錯會難上加難了🥲。