[譯] CSS 變數 + calc + rgb = 自動高對比度

慕逸發表於2019-03-11

原文在這裡

所有例子可以在文中的CODEPEN裡檢視


如你所知, 最近css的更新和附加功能非常得強大。 從Flex佈局到Grid佈局, 還有和我們這裡提及的-自定義屬性(又稱 CSS 變數), 使得強大的動態佈局還有介面, 比過去簡單, 並開拓了很多夢寐以求的可能。

幾天前, 我認為應該有一種方法, 使用自定義屬性的顏色作為一個元素的背景色, 和前景色形成對比(用黑或者白) 並足以通過WCAG AA訪問標準。

用javascript, 只需要短短几行程式碼就卓有成效。

var rgb = [255, 0, 0]; 

function setForegroundColor() {
    var sum = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000); 
    return (sum > 128) ? 'black' : 'white'; 
}
複製程式碼

一個元素的背景色選擇紅, 綠, 藍的值, 乘上一些特殊的數字(分別是299, 587, 144), 再想加, 然後除以1000, 當得到的值比128大, 將會返回黑色, 否則, 我們返回白色。 還不錯。

唯一的問題是, 當用css來重構時, 我們沒有原生的if來判斷值。 那麼, 我們如何用css來實現這個效果呢?

所幸, 如html一樣, css 非常寬容, 如果我們在RGB函式裡傳入一個大於255的值, 他會限制為255。 值一樣不可以小於0。 負數一樣會被限制為0, 所以, 測試值大於或者小於128, 我們用值減去128, 得到一個正數或者負整數。 然後, 如果我們乘一個很大的負數(如1000), 我們同樣會得到一個可以通過RGB函式的很大的正數或者負數。 如我所說, 值會按照瀏覽器的要求去限制。

這是一個使用CSS變數的例子

:root {
  --red: 28; 
  --green: 150; 
  --blue: 130; 

  --accessible-color: calc(
    (
      (
        (var(--red) * 299) +
        (var(--green) * 587) +
        (var(--blue) * 114) /
        1000
      ) - 128
    ) * -1000
  ); 
}

.button {
  color:
    rgb(
      var(--accessible-color), 
      var(--accessible-color), 
      var(--accessible-color)
    ); 
  background-color:
    rgb(
      var(--red), 
      var(--green), 
      var(--blue)
    ); 
}
複製程式碼

如果我數學沒錯~作者賣萌~我們得到了16, 758, 遠遠大於255, 輸入這個值到rgb函式裡, 瀏覽器會設定文字顏色為白色。

在這點上, chrome和firefox上都正常工作, 但safari 有些古怪, 給了一個不同的結果, 開始, 我認為, 這個可能是因為safari 沒有限制大值, 但經過一些測試, 我發現safari因為一些原因不喜歡我計算裡的除法。

仔細看看 calc 函式, 我注意到我可以去掉除以1000通過提升值從128到128, 000. 像這樣:

:root {
  --red: 28; 
  --green: 150; 
  --blue: 130; 

  --accessible-color: calc(
    (
      (
        (var(--red) * 299) +
        (var(--green) * 587) +
        (var(--blue) * 114)
      ) - 128000 /* HIGHLIGHT */
    ) * -1000
  ); 
}

.button {
  color:
    rgb(
      var(--accessible-color), 
      var(--accessible-color), 
      var(--accessible-color)
    ); 
  background-color:
    rgb(
      var(--red), 
      var(--green), 
      var(--blue)
    ); 
}
複製程式碼

滑動幾個範圍的滑塊, 以調整顏色值, 現在你可以看到, 一個能夠基於它的背景色切換文字顏色的動態元素, 並可以通過 WCAG AA 的標準。

CODEPEN

把這個概念放到實際應用中

下面是一個 用來展示如何配置使用者主題的 PEN 。 我已經複製並移動 --accessible-color 到需要它的特定的css規則, 以確保背景色基於前景色可見, 我 把 --accessible-color 變數在幾個地方乘以-1 。 顏色能夠通過控制右下側的控制器改變, 點選齒輪來配置他們。

CODEPEN

還有其他的方式來做

一會兒後, Facundo Corradini 在這片文章裡解釋如何做一些非常相似的事情, 他用一個有輕微差異的演算法與hsl函式組合起來。 他還會深入一些問題的細節關於提出這個概念的過程。

一些色調變得非常不確定(通常是黃色或者藍綠色), 他們顯示得比其他顏色(如紅色和藍色)要亮, 儘管他們有相同的亮度值。 因此, 一些顏色作為深色處理, 並讓白色的文字變得更加醒目

css的名字是什麼?

他提到 Edge 沒有限制大數字, 並且, 在我的測試中, 我注意到有時他們正常, 有時不正常。 如果任何人知道為什麼, 可以在評論裡自由分享。

此外, Ana Tudor 解釋了 如何使用 filter + mix-blend-mode 可以 幫助文字與更復雜的背景對比。 我的意思是相當地複雜, 她甚至證明了文字顏色如何隨著背景色改變而改變 - 令人驚歎!

同時, Robin Rendle 解釋瞭如何使用 mix-blend-mode 和 偽元素一起自動基於背景色反轉文字顏色。

因此, 將此視為另一種投入混合的方式。 自定義特性 開創了一些可能性, 並允許我們使用不同的方式, 來解決相同的問題。


補充相容性:

css變數相容性

相關文章