CSS 即將支持嵌套,SASS/LESS 等預(yù)處理器該何去何從

最近,有一則非常振奮人心的消息,CSS 即將原生支持嵌套 -- Agenda+ to publish FPWD of Nesting,表示 CSS 嵌套規(guī)范即將進(jìn)入規(guī)范的 FWPD 階段。
目前對應(yīng)的規(guī)范為 -- CSS Nesting Module。
隨著 CSS 自定義屬性(CSS Variable)的大規(guī)模兼容,到如今 CSS 即將支持嵌套,一些預(yù)處理器的核心功能已經(jīng)被 CSS 原生支持,這是否表示 SASS/LESS 等預(yù)處理器已無用武之地?即將被淘汰了?
規(guī)范的幾個(gè)階段
首先簡單介紹一下,一個(gè)規(guī)范從提出到落地,會(huì)經(jīng)歷的一些階段:
- 編輯草案 Editor's Draft (ED)
- 工作草案 Working Draft (WD)
- 過渡-最后通告工作草案 Transition – Last Call Working Draft (LCWD)
- 候選推薦標(biāo)準(zhǔn) Candidate Recommendation (CR)
- 過渡-建議推薦標(biāo)準(zhǔn) Transition – Proposed Recommendations (PR)
- 推薦標(biāo)準(zhǔn) Recommendation (REC)
上文說的,即將進(jìn)入 FPWD,只是處于規(guī)范的第 2 個(gè)階段 WD 階段,F(xiàn)PWD 表示第一次公開工作草案( First Public Working Draft (FPWD))。FPWD 后面還會(huì)有數(shù)個(gè)工作草案,會(huì)處理來自 CSSWG 內(nèi)部和小組外部更廣泛社會(huì)的反饋。完善規(guī)范的設(shè)計(jì)。
也就是說,目前來看,即便后面的流程順利,要等到瀏覽器大范圍實(shí)現(xiàn)該規(guī)范到能落地的那天還有非常長一段時(shí)間。
除此之外,我覺得 SASS\LESS 等預(yù)處理器還有一些比較有意思的功能(函數(shù)),是即便原生 CSS 支持了自定義屬性和嵌套之后依舊欠缺的,我簡單羅列羅列我的看法。
for() 循環(huán)函數(shù)
目前,原生 CSS 依舊不支持循環(huán)函數(shù)。
但是其實(shí)在預(yù)處理器中,循環(huán)還算是比較常用的一個(gè)功能??紤]下面這種布局:
ul
下面有多個(gè) li
,每個(gè) li 的高度遞增 20px
,一個(gè)一個(gè)寫當(dāng)然也可以,但是有了循環(huán)其實(shí)能極大減少工作量:
<ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul>
如果沒有預(yù)處理器,我們的 CSS 可能是這樣的:
ul { display: flex; align-items: baseline; justify-content: space-between; } li { width: 50px; background: #000; } li:nth-child(1) { height: 20px; } li:nth-child(2) { height: 40px; } // ... 3~9 li:nth-child(10) { height: 200px; }
如果利用 SASS 預(yù)處理器,可以簡化成:
ul { display: flex; align-items: baseline; justify-content: space-between; } li { width: 50px; background: #000; } @for $i from 1 through 10 { li:nth-child(#{$i}) { height: calc(#{$i} * 20px); } }
當(dāng)然,除此之外,在非常多的復(fù)雜 CSS 動(dòng)畫效果中,循環(huán)是非常非常常用的功能。
譬如一些粒子動(dòng)畫,我們通??赡苄枰ゲ倏v 50~100 個(gè)粒子,也就是 50~100 個(gè) div 的樣式,甚至更多,如果沒有循環(huán),一個(gè)一個(gè)去寫效率會(huì)大打折扣。
利用預(yù)處理器循環(huán)功能實(shí)現(xiàn)的一些效果展示
下面我簡單羅列一些我實(shí)現(xiàn)過的,運(yùn)用到了 CSS 預(yù)處理器循環(huán)功能的動(dòng)畫效果。
像上面這個(gè)使用純 CSS 實(shí)現(xiàn)的火焰效果,其中的火焰的動(dòng)態(tài)燃燒效果。其實(shí)是通過大量的細(xì)微粒子的運(yùn)動(dòng),配合濾鏡實(shí)現(xiàn)。
其中使用到了 SASS 的循環(huán)函數(shù)的片段:
@for $i from 1 to 200 { .g-ball:nth-child(#{$i}) { $width: #{random(50)}px; width: $width; height: $width; left: calc(#{(random(70))}px - 55px); } .g-ball:nth-child(#{$i}) { animation: movetop 1s linear -#{random(3000)/1000}s infinite; } }
嗯哼,上面的循環(huán)是循環(huán)了 200 次之多,如果真要一個(gè)一個(gè)寫,工作量還是非常巨大的。上述效果的完整代碼,你可以戳這里:
if() 條件語句
接下來一個(gè)就是 if() 條件語句。
其實(shí),CSS 中有一類非常類似條件語句的寫法,也就是媒體查詢 @media
以及 特性檢測 @supports
語句,目前 CSS 中支持的類似條件選擇的一些寫法如下:
@support 條件語句
CSS @supports 通過 CSS 語法來實(shí)現(xiàn)特性檢測,并在內(nèi)部 CSS 區(qū)塊中寫入如果特性檢測通過希望實(shí)現(xiàn)的 CSS 語句。
div { position:fixed; } @supports (position:sticky) { div { position:sticky; } }
上述 CSS 語句的意思是如果客戶端支持 position:sticky
,則采用 position:sticky
,否則,就是 position:fixed
。
關(guān)于 CSS 特性檢測的深入講解,你可以看看我的這篇文章:深入探討 CSS 特性檢測 @supports 與 Modernizr
@media 條件語句
另外一種常見的條件語句就是媒體查詢,這個(gè)大家還是比較熟悉的。
如果當(dāng)前設(shè)備滿足一種什么條件,則怎么樣怎么樣。
article { padding: 4rem; } @media screen and (min-width: 900px) { article { padding: 1rem 3rem; } }
嗯,并且,上述的兩種條件語句可以互相嵌套使用:
@supports (display: flex) { @media screen and (min-width: 900px) { article { display: flex; } } }
不過,上述兩種畢竟不是嚴(yán)格意義上的我們期待的 if()
語句。
很久之前,社區(qū)就有聲音(css-values - if() function),提議 CSS 規(guī)范中實(shí)現(xiàn) if()
條件語句,類似于這樣:
.foo { --calc: calc(10 * (1vw + 1vh) / 2); font-size: if(var(--calc) < 12px, 12px, var(--calc)); }
可以看到這一語句 if(var(--calc) < 12px, 12px, var(--calc))
類似于一個(gè)三元語句,還是比較好理解的。
然而,上述的條件語句一直沒得到支持的原因,在 scss-values - if() function 可以略窺一二。
原因是 CSS 一直在盡量避免在屬性當(dāng)中產(chǎn)生任意依賴。在 CSS 中,屬性之間本身存在一些隱式依賴,譬如 em
單位長度受到父元素的 font-size
的影響,如果作者能夠添加任意依賴關(guān)系(通過 if() 條件語句),那么將會(huì)導(dǎo)致一些問題。
原文是:this, unfortunately, means we're adding arbitrary dependencies between properties, something we've avoided doing so far because it's, in general, unresolvable.
Custom properties can arbitrarily refer to each other, but they're limited in what they can do, and have a somewhat reasonable "just become invalid" behavior when we notice a cycle. Cycles are more difficult to determine for arbitrary CSS, and can happen much more easily, because there are a number of existing, implicit between-property dependencies. For example, anything that takes a length relies on font-size (due to em), and so you can't have a value in font-size that refers to a property that takes a length (so no adjusting font-size to scale with width!). We add new dependencies of this sort over time (such as adding the lh unit, which induces a dependency on line-height); if authors could add arbitrary dependencies, we'd be unable to add new implicit ones for fear of breaking existing content (by forming cycles that were previous valid and non-cyclic).
所以,CSS 中的直接 if()
語句一直沒有得到實(shí)現(xiàn)。
SASS 等預(yù)處理器中的 if()
語句
最后,我們來看看預(yù)處理器中對 if()
的運(yùn)用,由于 SASS 等預(yù)處理器最終還是要編譯成 CSS 文件,所以 if()
其實(shí)并不太常用。因?yàn)?SASS 中的 if()
也無法實(shí)現(xiàn)類似上述說的 font-size: if(var(--calc) < 12px, 12px, var(--calc))
這種功能。
在 SASS 中,我認(rèn)為最常用的 if()
可能也就是這種場景:
@mixin triangle($size, $color, $direction) { height: 0; width: 0; border-color: transparent; border-style: solid; border-width: $size; @if $direction == up { border-bottom-color: $color; } @else if $direction == right { border-left-color: $color; } @else if $direction == down { border-top-color: $color; } @else if $direction == left { border-right-color: $color; } @else { @error "Unknown direction #{$direction}."; } } .next { @include triangle(5px, black, right); }
上述代碼是對 CSS 實(shí)現(xiàn)三角形的一個(gè)封裝,通過傳入的參數(shù),實(shí)現(xiàn)不同方向、顏色、大小的三角形。也就是預(yù)處理器中 if()
,更多的完成一些函數(shù)功能的封裝,方便復(fù)用。
實(shí)際上述的代碼會(huì)被編譯成:
.next { height: 0; width: 0; border-color: transparent; border-style: solid; border-width: 5px; border-left-color: black; }
Random() 隨機(jī)函數(shù)
OK,接下來這個(gè)是隨機(jī)函數(shù),是我個(gè)人在 SASS 等預(yù)處理器中最常用的一個(gè)函數(shù)。目前原生 CSS 不支持任意形式的隨機(jī)。
在 CSS 動(dòng)畫效果中,非常多的因素我們不希望是一成不變的,我們希望的是,一些屬性的值的產(chǎn)生由我們設(shè)定一個(gè)基礎(chǔ)規(guī)則,一個(gè)范圍中得到,這樣每次刷新都能產(chǎn)生不同的效果。
最常見的莫過于不同的顏色、不同的長度、不同的數(shù)量等等等等。
譬如下面這個(gè)使用 CSS 實(shí)現(xiàn)的效果:夏日夕陽圖。
我們通過隨機(jī),每次刷新都可以得到高度/寬度不一樣,位置不一樣的 div 塊,利用隨機(jī)的特性,繪制一幅幅不一樣的效果圖:
目前原生 CSS 不支持任意形式的隨機(jī)。使用預(yù)處理器,也只能是在編譯前編寫隨機(jī)函數(shù),SASS 中比較常用的隨機(jī)函數(shù)的一些寫法:
$r: random(100);
random()
是 SASS 支持的一種函數(shù),上述 $r 就能得到一個(gè) 0 ~ 100 的隨機(jī)整數(shù)。
利用 random()
,就能封裝出各種隨機(jī)函數(shù),譬如隨機(jī)顏色:
@function randomNum($max, $min: 0, $u: 1) { @return ($min + random($max)) * $u; } @function randomColor() { @return rgb(randomNum(255), randomNum(255), randomNum(255)); } div { background: randomColor(); }
關(guān)于原生 CSS 實(shí)現(xiàn) random() 的一些思考
下面這個(gè)是社區(qū)對原生 CSS 實(shí)現(xiàn) random() 函數(shù)的一些思考,感興趣的可以猛擊:
[css-values] random() function
簡單搬運(yùn)其中一些比較有意思的觀點(diǎn)。
假設(shè) CSS 原生實(shí)現(xiàn)了 random()
函數(shù),譬如下述這個(gè)寫法:
<p class="foo">123</p> <p class="foo">456</p> <p class="foo">789</p>
.foo:hover { color: rgb(random(0, 255), 0, 0); }
假設(shè)其中 ramdom()
是原生 CSS 實(shí)現(xiàn)的隨機(jī)函數(shù),有一些事情是需要被解決或者得到大家的認(rèn)可的:
random(0, 255)
的值在什么時(shí)候被確定,是在每一次 CSS 解析時(shí),還是每一次被應(yīng)用觸發(fā)時(shí)?- 對于上述 DEMO,3 個(gè)
.foo
的color
值是否一樣? - 對于反復(fù)的
hover
,取消hover
狀態(tài),random(0, 255)
的值是否會(huì)發(fā)生變化?
上述的問題可以歸結(jié)于如果 CSS 原生支持隨機(jī),隨機(jī)值的持久化和更新是必須要解決的問題??傊壳翱磥?,未來 CSS 原生支持隨機(jī)的可能性還是很大的。
工具函數(shù):顏色函數(shù)、數(shù)學(xué)函數(shù)
最后,我們再來看看一些有意思的工具函數(shù)。目前原生 CSS 暫時(shí)不支持一些比較復(fù)雜的顏色函數(shù)和數(shù)學(xué)函數(shù)。但是預(yù)處理器都帶有這些函數(shù)。
在我之前的一篇關(guān)于陰影的文章中 -- 你所不知道的 CSS 陰影技巧與細(xì)節(jié),介紹過一種利用多重陰影實(shí)現(xiàn)立體陰影的效果,譬如我們要實(shí)現(xiàn)下面這個(gè)效果:
其中的陰影的顏色變化就借助了 SASS 的顏色函數(shù):
fade-out
改變顏色的透明度,讓顏色更加透明desaturate
改變顏色的飽和度值,讓顏色更少的飽和
@function makelongrightshadow($color) { $val: 0px 0px $color; @for $i from 1 through 50 { $color: fade-out(desaturate($color, 1%), .02); $val: #{$val}, #{$i}px #{$i}px #{$color}; } @return $val; } p{ text-shadow: makelongrightshadow(hsla(14, 100%, 30%, 1)); }
當(dāng)然,除了上述的兩個(gè)顏色函數(shù),SASS 還提供了非常多類似的顏色相關(guān)的函數(shù),可以看看這里:Sass基礎(chǔ)—顏色函數(shù)。
除了顏色,數(shù)學(xué)函數(shù)也是經(jīng)常在 CSS 效果中會(huì)需要用到的。
我在這篇文章中 -- 在 CSS 中使用三角函數(shù)繪制曲線圖形及展示動(dòng)畫,專門講了如何利用 SASS 等預(yù)處理器實(shí)現(xiàn)三角函數(shù),以實(shí)現(xiàn)曲線線條,實(shí)現(xiàn)一些有意思的效果,像是這樣:
當(dāng)然,目前 SASS 也不支持三角函數(shù),但是我們可以利用 SASS function,實(shí)現(xiàn)一套三角函數(shù)代碼:
@function fact($number) { $value: 1; @if $number>0 { @for $i from 1 through $number { $value: $value * $i; } } @return $value; } @function pow($number, $exp) { $value: 1; @if $exp>0 { @for $i from 1 through $exp { $value: $value * $number; } } @else if $exp < 0 { @for $i from 1 through -$exp { $value: $value / $number; } } @return $value; } @function rad($angle) { $unit: unit($angle); $unitless: $angle / ($angle * 0 + 1); @if $unit==deg { $unitless: $unitless / 180 * pi(); } @return $unitless; } @function pi() { @return 3.14159265359; } @function sin($angle) { $sin: 0; $angle: rad($angle); // Iterate a bunch of times. @for $i from 0 through 20 { $sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1); } @return $sin; } @function cos($angle) { $cos: 0; $angle: rad($angle); // Iterate a bunch of times. @for $i from 0 through 20 { $cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i); } @return $cos; } @function tan($angle) { @return sin($angle) / cos($angle); }
就目前原生 CSS 而言,在數(shù)學(xué)函數(shù)等方面其實(shí)已經(jīng)做出了非常多的努力,譬如:
- 基礎(chǔ)運(yùn)算函數(shù)
calc()
- 比較函數(shù)
max()
、min()
、clamp()
等兼容性已經(jīng)逐漸鋪開,可以開始大規(guī)模使用,而類似于
- 指數(shù)函數(shù)
pow()
、sqrt()
、hypot()
、log()
、exp()
- 三角函數(shù)
sin()
、con()
、tan()
- 階梯函數(shù)
round()
、mod()
、rem()
等
也在規(guī)范 CSS Values and Units Module Level 4 中被提及定義,相信不久的將來也會(huì)逐漸落地。
關(guān)于社區(qū)對數(shù)學(xué)函數(shù)的一些討論,感興趣的也可以看看這里:Mathematical Expressions
總結(jié)一下
好了,綜上總結(jié)一下,就目前而言,我覺得 SASS/LESS 等預(yù)處理器在很多方面還是有有用武之地的,在上述的一些功能原生 CSS 沒有完全落地之前,預(yù)處理器能一定程度上彌補(bǔ) CSS 的不足。
并且,除去上述說的一些我個(gè)人認(rèn)為比較重要有意思的功能、函數(shù)之外,預(yù)處理器其它一些核心功能,譬如 extend、mixins 等也能有效的提升開發(fā)時(shí)的效率。
所以,在未來的一段時(shí)間內(nèi),我認(rèn)為預(yù)處理器還是能和 CSS 友好共存~
最后
好了,本文到此結(jié)束,希望對你有幫助 😃
更多精彩 CSS 效果可以關(guān)注我的 CSS 靈感
更多精彩 CSS 技術(shù)文章匯總在我的 Github -- iCSS ,持續(xù)更新,歡迎點(diǎn)個(gè) star 訂閱收藏。
到此這篇關(guān)于CSS 即將支持嵌套,SASS/LESS 等預(yù)處理器該何去何從的文章就介紹到這了,更多相關(guān)css嵌套內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
CSS實(shí)現(xiàn)多層嵌套結(jié)構(gòu)最外層旋轉(zhuǎn)其它層不旋轉(zhuǎn)效果
這篇文章主要介紹了CSS實(shí)現(xiàn)多層嵌套結(jié)構(gòu)最外層旋轉(zhuǎn)其它層不旋轉(zhuǎn)效果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨2020-02-05純css多種方法實(shí)現(xiàn)div中單行文字、多行文字及嵌套div垂直水平居中
經(jīng)常遇到要居中的問題,水平居中問題比較好解決,而垂直居中問題因?yàn)関ertical-align經(jīng)常失效,下面與大家分享下幾個(gè)不錯(cuò)的解決方法2014-04-24LESS 讓css也支持變量,運(yùn)算符,include,嵌套規(guī)則等等
最近在網(wǎng)上看到1個(gè)很有意思的CSS擴(kuò)展,這里介紹給大家。LESS 最早是1個(gè)ruby的gem,用于擴(kuò)展css的語法,用了LESS后,可以在css中使用變量,運(yùn)算符,include,嵌套規(guī)則等等。2010-07-04- 除非你的網(wǎng)站只有一頁,不然你一定會(huì)用的導(dǎo)航的.事實(shí)上,導(dǎo)航在網(wǎng)頁設(shè)計(jì)中是最重要部分之一.你要用很多時(shí)間去考慮如何讓瀏覽者更容易訪問你的網(wǎng)站.2009-11-30
- 網(wǎng)頁制作Webjx文章簡介:簡單學(xué)習(xí)css組合與CSS嵌套的寫法. CSS組合 你不必重復(fù)有相同屬性的多個(gè)選擇符,你只要用英文逗號(hào)(,)隔開選擇符就可以了2009-04-02