利用 Shell 腳本讓網站更具可讀性
如果希望人們發現你的網站實用,那麼他們需要能夠閱讀它。為文本選擇的顏色可能會影響網站的可讀性。不幸的是,網頁設計中的一種流行趨勢是在列印輸出文本時使用低對比度的顏色,就像在白色背景上的灰色文本。對於 Web 設計師來說,這也許看起來很酷,但對於許多閱讀它的人來說確實很困難。
W3C 提供了《 Web 內容可訪問性指南 》,其中包括幫助 Web 設計人員選擇易於區分文本和背景色的指導。z這就是所謂的「 對比度 」。 W3C 定義的對比度需要進行一些計算:給定兩種顏色,首先計算每種顏色的相對亮度,然後計算對比度。對比度在 1 到 21 的範圍內(通常寫為 1:1 到 21:1)。對比度越高,文本在背景下的突出程度就越高。例如,白色背景上的黑色文本非常醒目,對比度為 21:1。對比度為 1:1 的白色背景上的白色文本不可讀。
W3C 說,正文 的對比度至少應為 4.5:1,標題至少應為 3:1。但這似乎是最低限度的要求。W3C 還建議正文至少 7:1,標題至少 4.5:1。
計算對比度可能比較麻煩,因此最好將其自動化。我已經用這個方便的 Bash 腳本做到了這一點。通常,腳本執行以下操作:
- 獲取文本顏色和背景顏色
- 計算相對亮度
- 計算對比度
獲取顏色
你可能知道顯示器上的每種顏色都可以用紅色、綠色和藍色(R、G 和 B)來表示。要計算顏色的相對亮度,腳本需要知道顏色的紅、綠和藍的各個分量。理想情況下,腳本會將這些信息讀取為單獨的 R、G 和 B 值。 Web 設計人員可能知道他們喜歡的顏色的特定 RGB 代碼,但是大多數人不知道不同顏色的 RGB 值。作為一種替代的方法是,大多數人通過 「red」 或 「gold」 或 「maroon」 之類的名稱來引用顏色。
幸運的是,GNOME 的 Zenity 工具有一個顏色選擇器應用程序,可讓你使用不同的方法選擇顏色,然後用可預測的格式 rgb(R,G,B)
返回 RGB 值。使用 Zenity 可以輕鬆獲得顏色值:
color=$( zenity --title 'Set text color' --color-selection --color='black' )
如果用戶(意外地)單擊 「Cancel(取消)」 按鈕,腳本將假定一種顏色:
if [ $? -ne 0 ] ; then
echo '** color canceled .. assume black'
color='rgb(0,0,0)'
fi
腳本對背景顏色值也執行了類似的操作,將其設置為 $background
。
計算相對亮度
一旦你在 $color
中設置了前景色,並在 $background
中設置了背景色,下一步就是計算每種顏色的相對亮度。 W3C 提供了一個演算法 用以計算顏色的相對亮度。
對於 sRGB 色彩空間,一種顏色的相對亮度定義為:
L = 0.2126 R + 0.7152 G + 0.0722 * B
R、G 和 B 定義為:
if R sRGB <= 0.03928 then R = R sRGB/12.92
else R = ((R sRGB+0.055)/1.055) 2.4
if G sRGB <= 0.03928 then G = G sRGB/12.92
else G = ((G sRGB+0.055)/1.055) 2.4
if B sRGB <= 0.03928 then B = B sRGB/12.92
else B = ((B sRGB+0.055)/1.055) 2.4
R sRGB、G sRGB 和 B sRGB 定義為:
R sRGB = R 8bit/255
G sRGB = G 8bit/255
B sRGB = B 8bit/255
由於 Zenity 以 rgb(R,G,B)
的格式返回顏色值,因此腳本可以輕鬆拉取分隔開的 R、B 和 G 的值以計算相對亮度。AWK 可以使用逗號作為欄位分隔符(-F,
),並使用 substr()
字元串函數從 rgb(R,G,B)
中提取所要的顏色值:
R=$( echo $color | awk -F, '{print substr($1,5)}' )
G=$( echo $color | awk -F, '{print $2}' )
B=$( echo $color | awk -F, '{n=length($3); print substr($3,1,n-1)}' )
有關使用 AWK 提取和顯示數據的更多信息,查看 AWK 備忘表
最好使用 BC 計算器來計算最終的相對亮度。BC 支持計算中所需的簡單 if-then-else
,這使得這一過程變得簡單。但是由於 BC 無法使用非整數指數直接計算乘冪,因此需要使用自然對數替代它做一些額外的數學運算:
echo "scale=4
rsrgb=$R/255
gsrgb=$G/255
bsrgb=$B/255
if ( rsrgb <= 0.03928 ) r = rsrgb/12.92 else r = e( 2.4 * l((rsrgb+0.055)/1.055) )
if ( gsrgb <= 0.03928 ) g = gsrgb/12.92 else g = e( 2.4 * l((gsrgb+0.055)/1.055) )
if ( bsrgb <= 0.03928 ) b = bsrgb/12.92 else b = e( 2.4 * l((bsrgb+0.055)/1.055) )
0.2126 * r + 0.7152 * g + 0.0722 * b" | bc -l
這會將一些指令傳遞給 BC,包括作為相對亮度公式一部分的 if-then-else
語句。接下來 BC 列印出最終值。
計算對比度
利用文本顏色和背景顏色的相對亮度,腳本就可以計算對比度了。 W3C 確定對比度 是使用以下公式:
(L1 + 0.05) / (L2 + 0.05),這裡的 L1 是顏色較淺的相對亮度, L2 是顏色較深的相對亮度。
給定兩個相對亮度值 $r1
和 $r2
,使用 BC 計算器很容易計算對比度:
echo "scale=2
if ( $r1 > $r2 ) { l1=$r1; l2=$r2 } else { l1=$r2; l2=$r1 }
(l1 + 0.05) / (l2 + 0.05)" | bc
使用 if-then-else
語句確定哪個值($r1
或 $r2
)是較淺還是較深的顏色。BC 執行結果計算並列印結果,腳本可以將其存儲在變數中。
最終腳本
通過以上內容,我們可以將所有內容整合到一個最終腳本。 我使用 Zenity 在文本框中顯示最終結果:
#!/bin/sh
# script to calculate contrast ratio of colors
# read color and background color:
# zenity returns values like 'rgb(255,140,0)' and 'rgb(255,255,255)'
color=$( zenity --title 'Set text color' --color-selection --color='black' )
if [ $? -ne 0 ] ; then
echo '** color canceled .. assume black'
color='rgb(0,0,0)'
fi
background=$( zenity --title 'Set background color' --color-selection --color='white' )
if [ $? -ne 0 ] ; then
echo '** background canceled .. assume white'
background='rgb(255,255,255)'
fi
# compute relative luminance:
function luminance()
{
R=$( echo $1 | awk -F, '{print substr($1,5)}' )
G=$( echo $1 | awk -F, '{print $2}' )
B=$( echo $1 | awk -F, '{n=length($3); print substr($3,1,n-1)}' )
echo "scale=4
rsrgb=$R/255
gsrgb=$G/255
bsrgb=$B/255
if ( rsrgb <= 0.03928 ) r = rsrgb/12.92 else r = e( 2.4 * l((rsrgb+0.055)/1.055) )
if ( gsrgb <= 0.03928 ) g = gsrgb/12.92 else g = e( 2.4 * l((gsrgb+0.055)/1.055) )
if ( bsrgb <= 0.03928 ) b = bsrgb/12.92 else b = e( 2.4 * l((bsrgb+0.055)/1.055) )
0.2126 * r + 0.7152 * g + 0.0722 * b" | bc -l
}
lum1=$( luminance $color )
lum2=$( luminance $background )
# compute contrast
function contrast()
{
echo "scale=2
if ( $1 > $2 ) { l1=$1; l2=$2 } else { l1=$2; l2=$1 }
(l1 + 0.05) / (l2 + 0.05)" | bc
}
rel=$( contrast $lum1 $lum2 )
# print results
( cat<<EOF
Color is $color on $background
Contrast ratio is $rel
Contrast ratios can range from 1 to 21 (commonly written 1:1 to 21:1).
EOF
if [ ${rel%.*} -ge 4 ] ; then
echo "Ok for body text"
else
echo "Not good for body text"
fi
if [ ${rel%.*} -ge 3 ] ; then
echo "Ok for title text"
else
echo "Not good for title text"
fi
cat<<EOF
W3C 說明:
1.4.3 對比度(最小值):文本和文本圖像的視覺呈現方式的對比度至少為 4.5:1,但以下情況除外:(AA 級)
大文本:大文本和大文本圖像的對比度至少為 3:1;
附帶說明:作為非活動用戶界面組件一部分,純裝飾的,任何人都不可見或圖片的一部分包含特定的其他可視內容的文本或文本圖像沒有對比度要求。
小示意圖:徽標或商標名稱中的文本沒有最低對比度要求。
1.4.6 對比度(增強):文本和文本圖像的視覺表示具有至少 7:1 的對比度,但以下情況除外:(AAA 級)
大文本:大文本和大文本圖像的對比度至少為 4.5:1;
附帶說明:作為非活動用戶界面組件一部分,純裝飾的,任何人都不可見或圖片的一部分包含特定的其他可視內容的文本或文本圖像沒有對比度要求。
小示意圖:徽標或商標名稱中的文本沒有最低對比度要求。
EOF
) | zenity --text-info --title='Relative Luminance' --width=800 --height=600
最後,我希望提供有關 W3C 建議的參考信息,以提醒自己。
Zenity 顏色選擇器完成了所有解釋顏色的艱苦工作,用戶可以通過單擊色輪或輸入值來選擇顏色。 Zenity 接受網站上使用的標準十六進位顏色值,例如 #000000
或 #000
或 rgb(0,0,0)
(所有這些均為黑色)。這是白色背景上的黑色文本的示例計算:
Zenity 還識別標準的顏色名稱,如「cadetblue」、「orange」或「gold」。在Zenity 中輸入顏色名稱,然後點擊 Tab
鍵,Zenity 會將顏色名稱轉換為十六進位顏色值,如以下示例中對金色背景上的黑色文本的計算:
via: https://opensource.com/article/19/2/make-websites-more-readable-shell-script
作者:Jim Hall 選題:lujun9972 譯者:stevenzdg988 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive