【精心總結】CSS 你能見到的函數標記(上)

CSS 你能見到的函數標記(上)

與其餘任何編程語言都同樣,CSS 當中擁有許多函數,功能也是十分給力的,不少時候咱們已經使用了卻沒有注意到。最近複習 CSS 當中的知識點時,忽然發現咱們平時用到的 CSS 函數只是 CSS 大框架中的一小部分,因而對 CSS 函數標記的知識總結了一下,但願能對整個的 CSS 知識體系有更清晰的瞭解,可以幫助其餘人,也擴充本身的知識庫。css

在總結的時候斷斷續續發現了愈來愈多的函數,在發現新知識高興的同時,也注意到不少 CSS 的內容並無一份完整的草案能夠從頭看到尾,只能一點一點收集,不管是 w3.org 仍是 mdn 都面臨着難以收集完整信息的問題,可能會有遺漏,歡迎給我拍磚。html

總結不易,但願看官先贊後看,十分感謝!web

什麼是 CSS 函數標記

CSS 函數本來全稱叫作 CSS 函數標記(Functional Notations),它能夠用來表示 CSS 當中更復雜的類型或者調用一些特殊的處理方式。語法通常以函數名稱做爲開頭,而後左括號、參數、右括號,括號內能夠有空格,一樣能夠有多個參數,格式相似 CSS 屬性值。編程

當咱們須要實現一個須要計算的 CSS 樣式時,一般須要用到 JavaScript,但某些狀況下,一段 CSS 函數就能夠搞定。(若是是邏輯複雜的狀況,做者依然推薦使用 JavaScript 來實現效果,這可讓代碼在將來更容易維護。)canvas

句法以下:瀏覽器

selector {
  property: functional-notation( [argument]? [, argument]! );
}
複製代碼

固然直接看函數標記的句法,可能很難想象到平常使用的樣子。不利於理解,因此下面作個例子。服務器

舉個栗子

若是想實現以下圖效果:markdown

HTML 文本以下:網絡

<ol class="test">
            <li>Node
                <ol>
                    <li>Node
                        <ol>
                            <li>Node</li>
                            <li>Node</li>
                            <li>Node</li>
                        </ol>
                    </li>
                    <li>Node</li>
                </ol>
            </li>
            <li>Node</li>
            <li>Node</li>
        </ol>
複製代碼

做爲一個文檔的目錄,大批量的數據可能會從服務器請求過來,生成大量的 DOM 節點。常見的處理通常是在循環增長新節點的同時,可能會增長一個相似 <li><span style="color:red;">1.1.1</span><a href="">Node</a></li> 這樣的元素。這個時候咱們須要去拼接字符串以及循環的索引值,生成 1.1.1 這個號碼。app

for ( ... ) {
	// 已知的參數 index1, index2, index3...
	const str = `${index1}.${index2}.${index3}`
	// 下面的邏輯...
}
複製代碼

根據這份目錄嵌套的層級不一樣,會出現新的判斷邏輯。

但實際上這是徹底不須要的,邏輯上咱們不關心前面的號碼,甚至不該該經過 JavaScript 來生成序號的 DOM,做爲目錄咱們只關心渲染後面的文本。值得慶幸的是有其餘的方式實現上文序號的功能,其中之一能夠經過 CSS 的函數來輕鬆實現。

<style>
        ol{margin:0;padding:0;list-style:none;counter-reset:item;}
        li{padding-left:2em;}
        li:before{counter-increment:item;content:counters(item, ".") " ";color:#f00;}
</style>
複製代碼

引用這段 CSS 以後馬上發現,上面的 HTML 文本馬上變成了圖中顯示的樣子,經過 counters CSS 函數標記,輕鬆實現功能。

常見的 CSS 函數

爲了讓咱們更容易對這篇文章的知識有印象容易記憶,我將 CSS 中的函數進行了幾個分類:

  • 背景圖函數
  • 漸變函數
  • 顏色函數
  • 動畫函數
  • 圖形函數
  • 濾鏡函數
  • 轉換函數
  • 自定義屬性函數
  • 僞類選擇器函數
  • 網格函數
  • 數學函數

除了上面的分類,還特別分出了還在開發狀態,以及不推薦使用的函數:

  • 處於開發狀態的函數
  • 不推薦使用的函數

背景圖函數

背景圖函數顧名思義,是能夠設置元素背景圖屬性而使用的函數,固然函數的功能不必定只能設置背景圖片。

url()

url 函數是最多見的一個 CSS 函數了,它能夠連接到具體的資源並加載它們。包括圖像,字體,甚至其餘的級聯樣式表。固然出於對網頁性能的考量,最好限制加載資源的個數,畢竟每個請求都是一次 HTTP 請求,會影響其餘資源的加載。

@import('./other.css')

.test {
	background-image: url('https://sxyle.com/banner.png')
}
複製代碼

由於是一個十分常見的函數,不過多展開介紹,具體細節可查閱 MDN。

image()

Image 函數仍是一個 處於開發狀態的函數 ,本文寫做時尚未瀏覽器在正式環境中支持它,可是它強大實用的功能已經初現端倪。它的語法其實和 url 函數相似,可是它的區別在於能夠在圖像源地址後面添加媒體片斷標識符(沿 x 和 y 軸起點以及寬度和高度)來顯示源圖像的一部分。參數中定義的圖像部分將成爲獨立圖像。語法以下:

.back {
	background-image: image('https://sxyle.com/image.webp#xywh=0,20,40,60')
}
複製代碼

除了能夠顯示圖像的一部分,還能夠提供一個圖片的備選圖像:

.back {
	background-image: image('try.webp', 'try.svg', 'try.gif')
}
.back::before {
  content: image('try.webp', 'try.svg', 'try.gif')
}
複製代碼

總的來講是一個還處於草案狀態的 CSS 函數,但已經能夠看出具備足夠的潛力成爲將來之星哈。

element ()

element 函數目前僅有高版本 FireFox 瀏覽器經過前綴纔可使用,但它提供的功能也是十分讓人激動。它能夠從任意的 HTML 元素中生成做爲圖像的值。

單獨看定義可能稍微有點難以理解,若是換一種通俗的說法:element 函數可讓一個 DOM 元素做爲另外一個 DOM 元素的背景圖片,而且這個圖片是實時更新的,經過修改 DOM 元素能夠同時修改背景圖片。

<div style="width:400px; height:400px; background:-moz-element(#myBackground1) no-repeat;">
  <p>This box uses the element with the #myBackground1 ID as its background!</p>
</div>

<div style="overflow:hidden; height:0;">
  <div id="myBackground1" style="width:1024px; height:1024px; background-image: linear-gradient(to right, red, orange, yellow, white);">
  <p style="transform-origin:0 0; transform: rotate(45deg); color:white;">This text is part of the background. Cool, huh?</p>
  </div>
</div>
複製代碼

經過使用上面 -moz-element() ,能夠實現下面的效果:

這裏借用了 MDN 中的一個例子,可是能夠十分清晰的瞭解,經過 background:-moz-element(#myBackground1) no-repeat; 第二個 div 元素已經做爲第一個 div 元素的背景圖片了。

這個函數在 canvas 當中是至關實用的。

image-set()

使用這個函數,能夠基於瀏覽器對分辨率和網絡速度,指定圖像列表供瀏覽器選擇用做圖片背景,讓瀏覽器選擇最適合用戶的圖像。

.back {
	background-image: image-set("try.png" 1x, "try-2x.png" 2x, "try-print.png" 600dpi);
}
複製代碼

是一個十分加強用戶體驗的函數,在將來應該會有較大的使用場景,目前僅有少許瀏覽器能夠經過增長前綴的方式來使用。

漸變函數

首先先解釋一下漸變函數的意思,就是將一種顏色轉換爲多種其餘顏色時,會產生漸變。漸變函數幫助現代用戶界面增長了精緻美觀的設計方案,它能夠指定漸變的顏色、顏色在漸變區域的位置、漸變的角度。從兼容性來考慮,整體新的瀏覽器都還支持的能夠,在特定的生產環境中能夠沒有負擔的使用。

linear-gradient() 和 repeating-linear-gradient()

線形漸變函數應該是相比較其餘漸變函數,使用場景最多的一種。

.back {
	background: linear-gradient(#00c13c, #9198e5);
}
複製代碼

和其餘漸變函數同樣,函數沒有內在尺寸,函數的具體尺寸會和使用它的元素尺寸匹配。

線形漸變的具體參數還有漸變的角度和漸變的方位等等。

另外值得一提的是 repeating-linear-gradient() 函數,由於在 linear-gradient() 函數中實際上是不具備重複性的,所以經過重複漸變函數能夠實現不一樣的 CSS 樣式效果,以下:

.back {
  /* 一個傾斜45度的重複線性漸變, 從藍色開始漸變到紅色 */
  background: repeating-linear-gradient(45deg, blue, red);

  /* 一個從右下角到左上角的重複線性漸變, 從藍色開始漸變到紅色 */
  background: repeating-linear-gradient(to left top, blue, red);

  /* 一個由下至上的重複線性漸變, 從藍色開始,40%後變綠, 最後漸變到紅色 */
  background: repeating-linear-gradient(0deg, blue, green 40%, red);
 }
複製代碼

感興趣的小夥伴能夠本身體驗一下,學習知識最好的途徑就是實踐咯。

radial-gradient() 和 repeating-radial-gradient()

徑向漸變(Radial gradients)由其中心點邊緣形狀輪廓及位置、色值結束點(color stops)定義而成。

徑向漸變的中心點至邊緣形狀以及其延伸的部分,由連續縮放的若干同心輪廓組成,這個輪廓由設定的邊緣形狀決定。

徑向漸變與線形漸變很是類似,只是從中心點向外放射顏色變換,而不是直線。它們一般用於建立半透明的屏幕,以幫助將一個模擬彈窗與背景分開。

.back {
  background: radial-gradient(ellipse at center, #3053b9 0%, #5343ff 50%, #00ffff 50.25%, #00ffff 100%);
  height: 325px;
  width: 325px;
}
複製代碼

上面代碼的效果以下:

若是說線形漸變是一個冰冷無情的鐵圍牆,徑向漸變就是波光粼粼溫暖的湖面,一層一層泛着但願的光芒...

因爲漸變函數的參數都十分相似,因此能夠以一樣的參數來使用 repeating-radial-gradient() ,下面將參數稍微更改一下,並使用新函數:

.back {
  background: repeating-radial-gradient(ellipse at center, #cc1920 0%, #00c13c 10%, #cc1920 20%, #cccc11 30%);
  height: 325px;
  width: 325px;
}
複製代碼

效果以下:

這樣的效果若是配合上一些微妙的 css animation 效果,真的讓人眼花繚亂,你的網站今後再也不單調。(有的時候在想能不能把網站的廣告作成萬花筒的感受,一進網站就好像中了幻術...)

conic-gradient() 和 repeating-conical-gradient()

下面就是第三種漸變函數——圓錐漸變。圓錐漸變和徑向漸變的不一樣之處在於顏色是繞着圓進行旋轉。所以常常用來建立圓形進度條,畫一些圓形的效果動畫等等。然而圓錐漸變相比較上面兩種函數,兼容性並不樂觀,只有各個瀏覽器的較新版本才能夠支持它。

一個小例子:

.back {
  background: conic-gradient(
     #74103c 115deg, #00c13c 136deg 180deg, #99123c 100deg);
  border-radius: 50%;
}
複製代碼

以下所示:

咱們常見的餅圖,圓形進度條均可以用它來實現,十分的實用。下面再介紹一個使用圓錐漸變,實現的使人產生「幻覺」的代碼:

.back{
	background-image:
     repeating-conic-gradient(#fff 0 9deg, #000 9deg 18deg);
}
複製代碼

單單看這幾個屬性值可能很難想到它真正的效果,但若是看下面的示例圖片:

做者在看到這個效果的時候,真的眼睛很刺痛,好像看見太陽通常閃耀,產生眩暈感。可能這就是追星的感受吧...

顏色函數

CSS 中涉及顏色的地方十分多,咱們經常使用的有幾種定義顏色的方式:

  • 十六進制 (HEX)
  • RGB
  • HSL
  • 直接寫瀏覽器預約義的顏色名稱(black, white...)

關於 CSS Color Level 4 的顏色張鑫旭大佬也有一篇很細緻的講解,在這裏也分享給你們:CSS Color Level 4

固然除了這幾種方式還有其餘的 CSS 函數能夠供咱們使用,下面咱們先從常見的顏色函數開始:

rgb() 和 rgba()

rgb 函數可讓你使用數字來描述 r 的紅色、g 的綠色、以及 b 的藍色和 alpha 的透明度。十六進制顏色與 rgb 也能夠進行自由轉換。

rgb 函數使用起來也是十分簡單,通常狀況下 background: rgb(100, 200, 50) 就可使用。在舊版本的瀏覽器,使用 rgb 意味着放棄了 alpha 值的設置,默認就是 1,不透明,可是隨着 CSS 版本的推動,如今新版瀏覽器 rgb 函數也能夠設置第四個參數,做爲 alpha 值。甚至還可使用斜槓語法 background: rgb(100, 200, 50 / 0.4)

rgba 函數和 rgb 十分相似,若是對具體細節有興趣,能夠查看 w3.org 的 rgba 函數定義

hsl() 和 hsla ()

hsl 函數和 rgb 函數十分相似,可是描述的再也不是紅、黃、藍。而是色彩、飽和度、亮度三個參數。

但全部這些顏色表示的新語法中,#RRGGBBAA是最爲實用的,使用頻率是最高的,至於其餘一些新的語法,或者容錯性的加強,好當然好,可是平常開發鮮有機會用到。

條條大路通羅馬,因此原來那條路好好的,也就不必使用那些可能有坑的路。

這兩個函數的使用大致以下:

hsla(0, 100%, 50%, 80%)
  hsl(270 60% 50% / .15)
  hsl(270 60% 50% / 15%)
  hsl(270deg, 60%, 70%)
  hsl(4.71239rad, 60%, 70%)
  hsl(.75turn, 60%, 70%)
複製代碼

能夠看出兩種函數的語法很是自由,斜槓、百分比、角度、有無逗號的使用均可以,由於過於常見,很少深刻探討。

lch() 和 lab()

不少人應該和我同樣還不瞭解這兩個函數的意義,所以這裏摘一段百科:

Lab模式是根據Commission International Eclairage(CIE)在1931年所制定的一種測定顏色的國際標準創建的。於1976年被改進,而且命名的一種色彩模式。Lab顏色模型彌補了RGB和CMYK兩種色彩模式的不足。它是一種設備無關的顏色模型,也是一種基於生理特徵的顏色模型。 Lab顏色模型由三個要素組成,一個要素是亮度(L),a 和b是兩個顏色通道。a包括的顏色是從深綠色(低亮度值)到灰色(中亮度值)再到亮粉紅色(高亮度值);b是從亮藍色(低亮度值)到灰色(中亮度值)再到黃色(高亮度值)。所以,這種顏色混合後將產生具備明亮效果的色彩。

簡單來講是另外一種顏色測定的模式,而且它們是與設備無關的顏色。

接下來回到這兩個函數,它們還處於開發狀態,所以資料較少,只有在csswg這裏找到了部分細節。

CSS 容許直接在 lab 和 lch 函數中直接表達顏色

lab() = lab( <percentage> <number> <number> [ / <alpha-value> ]? )

lch() = lch( <percentage> <number> <hue> [ / <alpha-value> ]? )

光看句法可能很難理解,先說 lab 函數,它能夠接受 4 個參數,可是第四個爲可選參數。

  • 第一個參數爲 CIE 亮度,如同上面摘抄的百度百科,具體關於 CIE 亮度的問題能夠本身尋找,做者也不是十分了解,很少講述。

  • 第二個參數爲上面摘抄的顏色通道的 a 通道。

  • 第三個參數爲上面的顏色通道中的 b 通道。

  • 第四個參數做爲可選參數 alpha 值,和 rgb 函數的 alpha 十分相似。

很相似的是 lch 函數,一樣是 4 個參數,第四個參數依然是可選參數。

  • 第一個參數和 lab 函數的第一個參數同樣,一樣是 CIE 亮度。

  • 第二個參數是色度,大體表示顏色量,取值能夠從 0 取到 230,但若是是負值,是會取 0 的,超過 230 的話最終實際依然是 230,並不會出現語法錯誤。

  • 第三個參數很相似 hsl 函數的 <hue> 色相,能夠取值數字或者角度

  • 第四個參數與 lab 函數相同,做爲 alpha 值。

上面就是兩個函數的定義,目前 MDN 等網站資訊較少,想得到第一手資訊請關注 CSS 草案。

這兩個函數使用起來和其餘的顏色函數沒什麼差異:

lab(29.2345% 39.3825 20.0664);
  lab(52.2345% 40.1645 59.9971);
  lab(60.2345, -5.3654 58.956);
  lab(62.2345% -34.9638 47.7721);
  lab(67.5345% -8.6911 -41.6019);
  lch(29.2345% 44.2 27);
  lch(52.2345% 72.2 56.2);
  lch(60.2345% 59.2 95.2);
  lch(62.2345% 59.2 126.2);
  lch(67.5345% 42.5 258.2);
複製代碼

hwb()

先來了解一下,什麼是 hwb 函數吧:

HWB (short for Hue-Whiteness-Blackness) is another method of specifying colors, similar to HSL, but often even easier for humans to work with. It describes colors with a starting hue, then a degree of whiteness and blackness to mix into that base hue.

它是另外一種相似 hsl 定義顏色的函數方法,一般更容易使用,由於你只須要關心你想要的色相,而後適當的混入白色或者黑色就能夠獲得你想要的顏色。

句法以下:

hwb() = hwb( <hue> <percentage> <percentage> [ / <alpha-value> ]? )

若是是我,應該比較願意嘗試一下這種方法,固然若是不考慮兼容性的話。

  • 它的第一個參數和 hsl 相同的表示色相,具體能夠參考 hsl 函數的第一個參數。

  • 第二個參數是要混入的白色量,能夠從 0%100% 取值。

  • 第三個參數是要混入的黑色量,能夠從 0%100% 取值。

  • 第四個參數依然是 alpha 通道,與其餘函數相同,不做解釋。

color()

color 函數能夠在特定的色彩空間指定顏色,同時它也是取決於設備而產生顏色的函數。

句法以下:

color() = color( [ [<ident> | <dashed-ident>]? [ <number-percentage>+ | <string> ] [ / <alpha-value> ]? ]# , <color>? )

它是一個比較複雜的 CSS 函數標記,簡單的使用以下:

color(rec2020 0.42053 0.979780 0.00579, color(display-p3(0 1 0)));
複製代碼

上面使用 rec2020 色彩命名空間下使用這種石灰色,同時在 display-p3 屏幕上沒法顯示前面的顏色,將會使用後面做爲備選的顏色展現。

若是想了解更多,能夠查看具體的定義與細節,同時能夠先了解一下不常見的 @color-profile 規則。

device-cmyk()

device-cmyk 函數是最後一個要介紹的顏色函數了,它是一個與設備相關的顏色函數。若是你須要打印這種須要與設備相關的狀況時,這個函數可能會比較有用,由於實際打印出來是有色差的,可能與期待的結果相差甚遠。

句法以下:

device-cmyk() = device-cmyk( <cmyk-component>{4} [ / <alpha-value> ]? , <color>? ) <cmyk-component> = <number> | <percentage>

它一共接受 6 個參數,分別是:青色、品紅色、黃色、黑色成份,同時第 5 個參數與以前幾個函數的 alpha 值相同,第 6 個參數是備選參數。

Typically, print-based applications will actually store the used colors as CMYK, and send them to the printer in that form. However, such colors do not have a colorimetric interpretation, and thus cannot be used in gradients, compositing, blending and so on. As such, Device CMYK colors must be converted to an equivalent color.

打印機一般會儲存 CMYK 顏色,可是這些顏色不能進行漸變、合成、混合等操做。所以 device-cmyk 必須轉換爲一個近似的顏色。

它一樣涉及到不常見的 @color-profile 規則。能夠參考 color 一同窗習。

總結

隨着文字的堆砌,我學習以前,覺得 CSS 函數標記的內容是一灘細沙,我將它堆成了沙堡。但當我站在沙堡之上,忽然發現,它並非一灘沙,而是無數的石頭牆將沙困在這裏。因而我繼續攀登,終於登上了石頭牆,覺得將會獲得真諦,今後學會 CSS 玄幻奇妙的函數標記。沒成想石頭牆的那邊更加陡峭,若是想登上頂峯只能繼續攀登。 —黃梵高

說點人話就是:原本覺得 CSS 的知識只是比較難找,但開始尋找以後發現,真正難的是 CSS 函數自己和不少 CSS 存在的規則交錯在一塊兒,所以每個函數,均可能會有着難以理解的特性,須要反覆閱讀,查看文檔才能準確理解其意(已經存在中文文檔的能夠很方便的閱讀),固然可能會有人說我費這個力氣查看將來不必定存在的 CSS 規則是否有意義。

知識老是須要概括總結的,CSS 雖然比較雜,但只要梳理好知識結構,仍是能夠深刻學習的,有那麼多大佬已經鋪墊了堅實的長路,跟着巨人的步伐,也總結一下我學習的 CSS 函數標記吧!

最後求個贊b( ̄▽ ̄)d!

本週繼續更新剩下的 CSS 函數標記。

參考文獻

使用 CSS 的鎖實現的靈活的排版

張鑫旭的博客

csswg.org: #funcdef-color

MDN CSS 函數標記

w3.org: #Functional Notations

w3plus

css-tricks

相關文章
相關標籤/搜索