【譯】CSS 十六進制顏色揭祕

CSS 十六進制顏色揭祕

簡介

做爲一個長期在世界各地主持技術峯會的主持人,我有機會和許多技術傳播者交流,我將這些人稱爲「專業的技術做者」,忙於他們的工做。css

一個主題反覆出現的是 CSS 中的顏色 —— 特別是它們在 CSS 的屬性值中使用十六進制表示法。你能夠在你的 CSS 中各個地方看見這些看起來怪怪的字符串:#FF0080#9AC0B3#B5CBE8。個人意思是 #WTF,不是嗎?前端

雖然大部分的技術做者都會在某些時候遇到十六進制編碼的顏色值,它一般狀況下是一個模糊的問題,因此歷來沒有人花時間去解釋他們。我聽到最多的評論大都是這樣的:react

  • 我一直在使用十六進制編碼的色值,可是我真的不明白
  • 其實我知道一些十六進制編碼的色值表明什麼顏色,可是我不知道爲何
  • 有時候我能夠修改十六進制的編碼來達到我想要的效果,可是我不理解它們是怎麼工做的。
  • 使用一個像 #BADA55 這樣的不易理解的十六進制編碼是錯誤的嗎?

好的,就拿最後一個來講,可是答案是否認的,不,使用 #BADA55 這樣的十六進制表示顏色不是錯誤的。若是你是想要一個黃綠色,那麼你就可使用 #BADA55android

CSS 中的顏色

在 CSS 中顏色無處不在,它們能夠做爲前景、背景、陰影、表格、邊框、連接、底紋等等這些屬性的值。正由於顏色對於 CSS 是如此的重要,因此咱們須要一個通用、標準的方式來引用它們,以便在全部瀏覽器中獲得相同的顏色,這樣用戶就能夠看到做者但願展示的顏色。ios

在 CSS 中設置顏色有不少種方式,咱們稍後會討論其中的幾種。但本文的重點是十六進制顏色,由於它具備明確性、一致性,並且還十分優雅。雖然它有這麼多優勢,可是有個缺點就是它並非很直觀。git

物理學

讓咱們從色彩的基本原理開始:白光實際上是由彩虹的全部顏色組成。知道 Roy G. Biv 嗎?它是紅、橙、黃、綠、藍、靛、紫七種顏色的英文首字母縮略詞,咱們看到的白光僅僅是有這七種顏色混合組成的。github

若是你認爲這是一個笑話,那麼你太年輕了
若是你認爲這是一個笑話,那麼你太年輕了

顏料

要了解顏色是如何工做的,讓咱們先來回顧一下顏料中的物理光線。後端

顏料的三原色
顏料的三原色

學習顏料的第一件事情就是你能夠把原色組合成第二種顏色。例如,你能夠將藍色和紅色混合在一塊兒獲得紫色。一樣,還有其餘的選擇,你能夠將紅色和黃色混合成橙色,黃色和藍色混合成綠色 —— 全新的第二種顏色。瀏覽器

顏料中的生成色
顏料中的生成色

你當時不知道的是它的成色原理:顏料減色法原理。也就是說,它們吸取或減去白光中的某些色光,只反射它們沒有減去的光。ide

對於那些沒有試驗過的人來講,這意味着一個看起來是單一顏色的物體實際上不是那種顏色。由於物體吸取了全部的光波長,可是隻反射回來一種顏色的光(咱們看到的),它其實是全部的顏色。換句話說,是除了它顯示的顏色以外的全部顏色。咱們看到的橘色實際上並非橙色。雖然不符合常理,但事實如此。

在不知道它的物理特性的狀況下,咱們早都理解將兩種或兩種以上的顏色組合在一塊兒會獲得其餘顏色,並且咱們添加的顏色越多,新的顏色就越多,每種顏色都比原色更深。咱們最終了解到,若是把全部的顏色混合在一塊兒,咱們最終會獲得黑色,或者是很是接近黑色的顏色。咱們如今知道,這是由於從原來的白光開始,隨着愈來愈多的顏料被加入,愈來愈多的光被吸取或減去。因此,明顯的是,光線越少 = 顏色越深。 提示:請記住這一點,這在後面將會很重要。

很是很是深的灰色就接近黑色
很是很是深的灰色就接近黑色

咱們發現顏料混合的另外一件事是,除了被混合的顏色外,混合顏色的比列也會影響結果。即同爲藍黃混合,黃色多一點,會產生一個淡淡的「春綠」,而藍色多一點則會產生一個暗暗的「森林綠」。因此很明顯,混合的比例也很重要。

色光

你明白了嗎?那好,如今忘了它,由於全部的計算機屏幕都是基於光而不是顏料。顏料的知識只是爲光學作準備,稍後你會感謝個人。事實證實,光學的物理現象是和顏料相同的,只是稍有不一樣(這是真的)。

就像上面討論顏料同樣,咱們先從原色開始,在光學上它們是紅色、綠色和藍色。

咱們一塊兒來看,這可能有一點粗糙
咱們一塊兒來看,這可能有一點粗糙

就像顏料同樣,咱們能夠將原色混合得到第二種顏色。而且,就和顏料同樣,而且也有不少種混合結果。藍光和紅光混合獲得名爲 purple-y 的顏色,咱們稱之爲洋紅;綠光和藍光混合獲得名爲 teal-y 的顏色,咱們稱爲青色;好吧,很合理,有紅燈了也有綠燈了……什麼?!?

是的,最後一個確實和前面的不同,並不像直觀感覺的那樣,可是這就是光學的工做原理:紅光和綠光相加獲得黃光。

這是爲何呢?原本就是如此,光學的工做原理就是這樣的。你可能會對此感到困惑,若是對此感到困惑,你能夠諮詢這裏面的 專家

這是由於色光是加色法,和顏料相反。咱們組合的光波波長越多,新的顏色就越多,直到全部顏色都以最大比例混合時 —— 最終將獲得白光。很容易看出,咱們獲得的每一種混合色都比它的原色更亮。所以,對於顏料咱們的推論是:光線越少 = 顏色越深,而對於色光則是:光線越多 = 顏色越亮

三種原色的光彙集在一塊兒就成了白光
三種原色的光彙集在一塊兒就成了白光

回到 CSS

在 CSS 中,咱們要達到預期的顏色效果,咱們須要一種方式,不只指定選哪種原色,並且還要指定每一種顏色的比例。也就是說,咱們須要精確地指定多少紅色、綠色和藍色的光線相加以得到特定的顏色。嘿,這是物理學!

在計算機世界,值的範圍通常是在 0-255 之間。固然,這是有緣由的,但如今你能夠不用在乎。由於要解釋二進制是如何工做的,是另外一篇文章的內容。如今,請相信我,每種顏色的最小值是 0,最大值是 255,謝謝。

設置顏色的方法

雖然我在本文中提倡十六進制表示色值的方法,但我不能忽視這一事實,它決不是惟一指定 CSS 顏色的方法。在繼續以前,讓咱們快速看看其餘三種方法。

注意: 若是你對這部分的內容徹底不感興趣,你能夠直接跳到下一主題,快速瀏覽。說真的,你不會錯過任何關於十六進制的重要信息。這個小插曲主要是將來完整性,很大程度上是爲了不文末出現大量「可是,可是,可是...」的評論。

顏色名

經過顏色名設置顏色是一種簡單的方式,全部現代瀏覽器都能解釋各類顏色名,它們能夠用做 CSS 屬性值。不少名字都頗有道理,好比 black(黑)、white(白)、red(紅)、green(綠)、blue(藍)、yellow(黃)、purple(紫)、orange(橙)等等。有些不是很明顯,像 aquamarine(海藍寶石),blueviolet(藍紫色),cornsilk(花絲),khaki(卡其布)。而後有些是荒謬的,像 aliceblue(愛麗絲藍)、lavenderblush(淡紫紅)、burlywood(原木色)、和 gainsboro(淡灰色)。

問題是,顏色名不夠靈活,也不常見。purple 只對應一種顏色,那就是「紫色」。若是你想要一個特定的紫色,好比「淡紫」、「薰衣草紫」,那它作不到。固然,有 「mediumorchid」、「plum」 和 「thistle」 這些名稱可供選擇,但這些可能並非你想要的顏色,而且你怎麼經過名稱知道是什麼顏色呢?正如剛纔提到的,名稱越奇特,顏色越不直觀。我認爲沒有人能猜到 「peru」 是什麼顏色。

例如,這是一個有紅色背景的黃色文本,使用顏色名設置:

span.hilite { color: yellow; background-color: red; }

RGB

另外一種方法被稱爲 RGB,對於……嗯,我但願你能解決那個問題。這種方法使用普通的數字,而且至關整齊地用十進制記數法或百分比指定每一個顏色的比例。但這種方法,冗長並複雜;有額外的括號,逗號,和/或百分比符號,很容易寫成不是你想要的顏色或者出錯。

這是一個有紅色背景的黃色文本,使用 RGB 設置:

span.hilite { color: rgb(255, 255, 0); background-color: rgb(255, 0, 0); }

或者

span.hilite { color: rgb(100%, 100%, 0%); background-color: rgb(100%, 0%, 0%); }

HSL

只是爲了進一步把水攪渾,另外一種方法稱爲 HSL,分別表示色調,飽和度,亮度。這種方法 —— 具備多種我不想使用的子方法,使用十進制值和百分比的值。十進制值表示色輪上的顏色從 0 到 360,其中 0 是紅色,120 是綠色,240 是藍色。百分比表示光的數量,其中 0% 是無色的,100% 是全色的。亮度百分比而後修改顏色的亮度或光度,其中 0% 是黑色的,100% 是白色的。我一直以爲這個方法有點混亂,根據個人經驗,開發人員不多使用這種方法。

這是一個有紅色背景的黃色文本,使用 HSL 設置:

span.hilite { color: hsl(60, 100%, 50%); background-color: hsl(0, 100%, 50%) }

十六進制表示

另一種,十六進制記數法,一般是最流行的 CSS 顏色命名方法。它是具體的、一致的、緊湊的和精確的。使用三個字符的十六進制碼在範圍 00-FF 的指定 RGB 值,其中 00 是沒有顏色和 FF 是全部顏色彙集在一塊兒造成的白色。

這是一個有紅色背景的黃色文本,使用十六進制色值設置:

span.hilite { color: #FFFF00; background-color: #FF0000; }

好了,這就夠了,讓咱們繼續來看!

快速的回顧一下

我知道你認爲我在撒謊,但十六進制真的比你想象的容易。十六進制色值是基於十六進制(基數爲 16)計算的。爲了理解十六進制是如何工做的,你只須要理解十進制(基數爲 10)是如何工做的。哦,等等,你已經作了!很好,讓咱們回顧一下。

請不要跳過這部分,好嗎?我知道你理解十進制是怎樣工做的,我想讓你想一下爲何它能起做用。

十進制系統有十個單字符數字,0 到 9。你能夠一直加一來得到下一個數字,但最終你將用完數字。當這種狀況發生時,你把一個 0 放在這個位置,而後在左邊再增長一位數。讓咱們來思考一下這句話的含義。

這裏最重要的一點是,位置的名字表示它們中的數字的值,而每一個位置的名稱表明的最大值,在其右邊的位置表示。在十進制中,最右邊的位置稱爲「個位」,右邊的第二個位置稱爲「十位」。數字「9」的意思是「九個一」,若是咱們加上「1」(「一個一」),咱們就用完了數字,因此咱們就在個位放了一個 0,在十位放了一個 1,獲得了兩位數 10。

所以,十進制值 10,咱們稱之爲「十」,實際上表示「一個十和零個一」。一樣,十進制的 26 表示「兩個十和六個一」,十進制的 33 表示「三個十和三個一」,十進制的 42 表示「四個十和兩個二」。(固然, 這就是最終問題的答案 )。

十六進制的偉大之處在於它工做得很像十進制。確切地說! 不開玩笑、不誇張、而且你也只能選擇使用十進制的方式理解十六進制。十六進制算術和十進制算術徹底同樣,它只有十六個字符數字而不是十個數字。

將 A ~ F 視爲數字,對應十進制中的 10 ~ 15。固然,計算機是對你友好的才提出多出這六個數字,但(a)咱們必需要學習他們,(b)如何在鍵盤輸入。(c)那東西是什麼,他們只是在字母最小的惡做劇。

換句話說,十進制值 10 用十六進制的一個數字 A 表示,這表示「十個一」。十六進制數字 B 表示「十一個一」,等等,直到 F,表示「十五個一」。

重複一遍,就和十進制同樣,每個位置的名字表示它們中的數字的值,每一個位置的名稱表明的最大值能夠在其右邊的位置表示。最右邊的地方仍被稱爲「一」,咱們如今能夠數到 F(「十五個一」),右邊起第二位被稱爲「16」。

十六進制加法:9 + 1 = a
十六進制加法:9 + 1 = a

數字「9」還表示「九個一」,但如今,若是咱們加上「1」(「一個一」)的話,咱們尚未用完的數字,因此咱們能夠在個位使用 A(「十個一」),只須要讓十六顯示爲兩位數。

就像十進制同樣,你能夠不斷地增長一個數字來得到下一個數字,可是你仍然會用完數字。當這種狀況發生時,你把一個 0 放在這個位置,而後在這位數的左邊新增一位數。就和十進制同樣,再讓咱們想一想這句話的意思。

十六進制加法:f + 1 = 10
十六進制加法:f + 1 = 10

因此,10(數字 1 和數字 0)的十六進制值不是十,而是十六,由於它的表示「一個十六,零個一」。然而,就像十進制同樣,任何兩位數字的十六進制數字均可以用一樣的方式讀取和理解。這意味着,若是咱們繼續計數遞增到十六的時咱們就使用「F」,重點來了:咱們可使用十六進制的兩位數從 00 到 FF 表明任何從 0 到 255 的十進制數

例如,在下面的圖表中,十六進制的 14(也就是「數字一和數字四」)是十進制的二十,由於它其實是一個十六(16)和四個一(1),在十進制中 16 + 4 = 20。十六進制的 A5 表明着一百六十五,由於由於它是十個十六(10 16 = 160)和五個一(1 5 = 5)。最終,要特別注意紅色的線,由於他們是最終的範圍和範圍的中間點:十六進制的 00(數字零和數字零)是零,十六進制的 FF 是二百五十五(15 16 + 15 = 255),而且十六進制的 80(數字八和數字零)是一百二十八(8 16 + 0 * 1 = 128),是 00 和 FF 的中間值。提示:記住 「80」 是中間點,咱們立刻就要用到它。

十六進制計數,00 到 FF
十六進制計數,00 到 FF

請和我一塊兒繼續

讓咱們在這裏喘口氣,由於這個計數方案是整個事情的關鍵,是理解十六進制表示顏色的關鍵。但請不要讓它更難理解;我不是在開玩笑,十六進制,真的真的真的和十進制工做原理同樣。這些概念是徹底相同的;在到達下一位數以前十六進制只不過是多了幾個可用的數字。

在你繼續以前,必定要理解這個概念。如下是一些十六進制轉換爲十進制的例子。

  • 1F = 一個十六和十五個一 = 十進制的 16 + 15 = 31
  • 2B = 兩個十六和十一個一 = 十進制的 32 + 11 = 43
  • 41 = 四個十六和一個一 = 十進制的 64 + 1 = 65
  • AA = 十個十六和十個一 = 十進制的 160 + 10 = 170
  • F0 = 十五個十六和零個一 = 十進制的 240 + 0 = 240

看,一旦你掌握了竅門就很容易了。這只是數學。只不過是使用字母來表示數字。

所以,三個兩位數的十六進制數字,從 00(0)到 FF(255),將在 CSS 顏色屬性值中表示紅色、藍色和綠色的程度。

直觀性

如今咱們明白如何將基色混合和如何指定的每個顏色的程度,應該明確的是,咱們能夠在整整六個十六進制數字產生任何顏色代碼,從 #000000#FFFFFF,前面兩位表示紅色,中間兩位表示綠色,最後兩位表示藍色 - 始終是 RGB 這個順序。

咱們能夠用六個十六進制數字編碼多少種顏色?嗯,這 FFFFFF 是十進制的 16777216 ,因此正確答案是「一堆」。

當咱們指定 CSS 進制顏色代碼以前,咱們以「#」,稱爲英鎊符號井號。CSS 就是這樣知道下面是一個十六進制的顏色代碼。另外,字母大小寫沒關係,CSS 中 #a94cb3#a94cb3 是相同的。

瞭解這些以後,一些顏色代碼你就應該知道怎樣表達了,像黑色、白色和三基色。

十六進制的黑色、白色和三基色
十六進制的黑色、白色和三基色

這很簡單,對吧?這是光的物理原理:在這些顏色代碼中,每一個 RGB 份量要麼是「零」(00),要麼是「所有」(FF)。因此,例如,#000000 表示黑色。看這些零;沒有紅色,沒有綠色,沒有藍色 - 沒有光源 - 沒有光不就是黑色嗎?(若是你說「暗的」,你被解僱了。)一樣,#FF0000 表明紅色。該代碼指定徹底紅色,沒有綠色,也沒有藍色。只有紅色的光。只表明紅色。沒有其餘的可能,必須是紅色,正紅。

無論你信不信,咱們接着往下看,由於一旦你掌握了這個想法,其餘顏色也開始變得直觀了。如今你應該將十六進制代碼看作的顏色,由於他們就是顏色。

考慮三基色,洋紅(全紅色,沒有綠色,沒有藍色)青色(沒有紅色,全綠色,全藍色),黃色(可直觀的全紅色,全綠色,沒有藍色)。建立這些顏色的十六進制代碼如今應該是顯而易見的。

十六進制顏色值
十六進制顏色值

好的,到目前爲止,咱們仍然只使用「沒有」或「所有」值。但回想十六進制的 80(「數字八和數字零」)是 00 和 FF 的中間,因此咱們如今應該可以使用這個值,方便地構建一些半光的顏色代碼 —— 即代碼建立深色調的初級和中級的顏色。嗯,我想知道那些會是什麼樣子的?可能像這樣。

十六進制初級和中級半色調
十六進制初級和中級半色調

咱們在這裏作的,經過改變三個份量的值,僅僅是改變了光的數量,咱們把代碼放入每種顏色的代碼中,從沒有(00) 到一半(80) 到所有(FF),這個事實使咱們有點頓悟。好吧,一個巨大的巨大的巨大的巨大的頓悟。實際上兩個。

更高的數字 = 更多的光線 = 接近白色 = 明亮的顏色。

較低的數字 = 較少的光線 = 接近黑色 = 較暗的顏色。

這些真的很重要,請再讀一遍。

小測驗

讓咱們來作一些使用代碼表示顏色的小測試,來吧,這將是頗有趣的!用純文字回答這些問題(不是十六進制代碼),而後向下輪動一點來顯示答案。

問題 1. 若是 #FF00FF 是亮紅色而且 #800080 是暗紅色,那麼 #B000B0 是什麼呢?

問題 2. 若是 #00FFFF 是亮青色而且 #008080 是暗青色(也被稱爲綠色),那麼 #004040 是什麼呢?

問題 3. 若是 #000000 是黑色而且 #ffffff 是白色的,那麼 #010101#323232 表明什麼顏色的範圍呢?

…向下滾動

…接着向下

…繼續

…再向下滾動一點

…立刻就到了

答案 1: #B000B0 是中等亮度的 亮紅和暗紅色之間的地方,由於 B0 小於 FF 但超過 80。

答案 2: #004040 比暗青色暗的顏色,由於 40 小於 FF 和 80。

答案 3: #010101#323232五十種深淺不一樣的灰色,由於十六進制的 32 等於十進制的 50:3 16 + 2 1 = 50。

事實上,最後一個的問題使咱們頓悟了一個更多而且細微,雖然不是特別偉大但又是很是重要的道理:

當全部三個色值相同時,無論值是多少,顏色都是灰色的

確實是這樣的,#232323#a9a9a9#4b4b4b#2f2f2f#959595#dadada 和全部其餘具備相同的 RGB 值的組合都是灰色 —— 有些更暗一些,一些更亮一些。並且,由於十六進制的 80 是 00 和 FF 的中間值,這意味着 #808080 是全部灰色的中間色。是的,「灰色」包括黑色 #000000 和白色 #ffffff;這意味着,真的有 256 種的灰色。

實際的例子

讓咱們來靠近一些實際的 CSS 顏色編碼的示例。基於你對十六進制和顏色的新知識,你應該可以理解爲何這些十六進制的顏色值能夠表示他們想要表達的顏色。看看這些 CSS 規則中的代碼而且想一下這三對十六進制的數字表示什麼顏色,你應該馬上可以回答上來。

例 1:在這裏,文本的前景色設置爲深藍色而且背景色設置爲偏淺一點的中灰色。

例 1
例 1

例 2:在這裏,任何帶有類名爲「warning」的元素將設置爲黃色背景紅色文字(注意,根據上述規則,背景仍爲灰色,假設這些都在同一個頁面中。

例 2
例 2

例 3:在這裏,正常的連接顯示爲藍綠色的文本,而在懸浮樣式設置爲白色文字藍綠色背景。(仍然在灰色頁面背景下。)

例 3
例 3

例 4:最後,這個塊的背景爲淺棕色(淡黃色),一個棕色的邊框,和深褐色的文本。(都在相同的灰色頁面背景下。)

例 4
例 4

簡寫

我要說的是你能夠將十六進制的六位 CSS 顏色值簡寫是爲三位,可是請不要這樣,這對平面設設計師不利。

首先,縮寫一般會致使意外的顏色。只有當一個顏色值的兩個十六進制數字相同,如 FF,88,或 22 時,縮寫纔是準確的。例如,#fff#ffffff 相同,#d09#dd0099 是同樣的。可是若是原始顏色的十六進制數字就不相同,那麼縮寫的代碼只會「看起來像」原始顏色,也就是說和原始顏色很接近,可是又不徹底相同。例如:#080#008800 同樣,可是確定和 #008000同樣的,#a4d#aa44dd 是相同的,和 #a040d0不一樣的

其次,即便是正確使用縮寫,它也不多被一致地使用,在全局搜索中就可能出問題或者是無用的。若是你的 CSS 代碼中使用 #4be 而其餘人使用 #44bbee,稍後找到你須要你改變這個顏色,這就會產生匹配的問題。即便是簡單的代碼 #000#000000 也不榮易進行匹配和替換。

第三,顏色值的縮寫僅僅能減小三個字節,這弊大於利。

總結

讓咱們來總結一下。這裏要明確一點的是,十六進制並不難,和十進制不一樣的只是多了幾個數字。你要記住你要處理的數據是的十進制表示是 0-255,可是寫成十六進制的兩位數表示就是 00-FF。一旦你接受了十六進制的基數是 16,你將會發現它與是基數爲 10 的十進制原理是同樣的。十六進制的顏色代碼將表現的更爲直觀。

有些人明白了,但有些人仍是不明白
有些人明白了,但有些人仍是不明白

記住,它老是三對十六進制數字,老是以紅-綠-藍的順序排列,更高的數字老是意味着更加明亮的顏色(反之亦然)。

如今花一點時間將你的手臂在你身後,拍拍本身的背,放鬆一下。你如今知道一些你的 98% 的同伴都不瞭解的知識!

參考文獻

色彩部分

十六進制部分

工具

集成工具

集成工具一般容許您選擇一個顏色並查看其代碼,或者輸入代碼來顯示顏色,例如谷歌瀏覽器的開發者工具備一個集成的顏色選擇器,Mac 的 Sublime Text 也有一個顏色選擇器的插件

其餘

感謝!

謝謝你閱讀這篇文章,我但願你在這一過程當中得到了樂趣並學到了一些東西!評論或問題?能夠在 dave@davegash.com 中聯繫做者,Dave Gash。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索