為什麼一直沒有出現一個可以把現代 CSS 編譯為支持老版本瀏覽器 CSS 的編譯工具?
意思就是開發者只針對新瀏覽器寫樣式,而且根據這個編譯工具的文檔,避開一些它無法支持的屬性或屬性組合,然後由這個編譯工具把寫好的CSS編譯成能夠支持低版本瀏覽器的CSS代碼。
比如說我要實現三列等高布局,我就用flex寫,但避開那些這款編譯工具無法支持的屬性比如space-around(假設),然後編譯工具把我用flex寫的代碼編譯成用float實現的,然後讓它跑在老版本瀏覽器上,這樣我即可以用新的CSS功能,又可以兼容老瀏覽器。當然這裡會出現一個哲學問題,就是如果你用flex來實現以前用float就可以實現的功能,那要flex還有什麼用呢?但我覺得這還是有一定意義的,首先就是可以保證CSS代碼的簡潔(因為用flex實現相同的布局應該要比float簡潔高效),同時在不想支持老版本瀏覽器的時候,就可以停止對老瀏覽器的編譯,並且在新版本的瀏覽器上直接使用手寫好的CSS而不是編譯得出的CSS。嗯,這裡請不要把這個「編譯工具」與Sass/Compass/Less等CSS預處理器做比較,這裡說的編譯工具是對CSS代碼進行同義轉換,而這些預處理器的作用主要是解決嵌套選擇器,變數等功能,而不是同義轉換。我覺得可以明顯類比的就是JS的Bable可以把ES6的語法和功能轉換成同等作用的ES5代碼一樣而這裡的編譯工具就是把高版本的CSS代碼轉換成在低版本上有相同布局及樣式的代碼這個功能。以及能夠處理掉一些解決方案非常明確的兼容性問題的代碼。但同時也對不能實現的功能進行優雅降級,比如說不支持圓角的地方就不用好了,對布局的影響並不是特別大。不知道我有沒有講清楚,請高手繼續補充~
題主的思路不錯,不過實踐起來可不容易。
其實類似的實踐早已有之,如 Dean Edwards 著名的 IE7 項目(2003年)。但該項目並非預編譯,而是在運行時解析 CSS 並實現效果。
我受到 IE7 項目的啟發,描述過另一種讓IE6瀏覽器支持多class選擇器的方法(面向未來的CSS實踐,2006年),更靠近靜態而非運行時,相對更接近題主預編譯思路。
CSS 預處理器/後處理器及其庫或擴展其實包含了類似的功能,比如將 flex 轉換為幾種不同草案語法。
今天 ShadowDOM 的 polyfill 方案,是最典型的符合題主預期的樣式編譯步驟。
但是這些工具要麼是用途局限,要麼是效果有限,很難完全達到題主期望的目標。原因如下:
1. CSS 與 JS 非常不同。ES6 的新特性許多是語法糖,或者說很容易有語義等價或近似等價的 ES5 形式。但是 CSS 的新特性中,除了極少數(如 hsl =&> rgb,草案的語法變遷,屬性拆解等)有等價或近似等價轉換,絕大多數是不可能映射到既有特性上的(如果可以的話,也就沒有必要加新特性)。像 flex 寫成 float ,只是在滿足許多先決條件的情況下效果類似,但實際行為的差別是巨大的。
2. CSS 很複雜,每個特性可能有許多隱含的效果。比如用 float 之後,就產生了 BFC 從而會影響許多其他屬性的行為。更不用說你徵用了某個屬性去達到其他效果之後,與其他需要該屬性的需求可能產生衝突。
3. 即使只考慮效果類似,很可能需要牽涉 HTML 和 JS 輔助,單單編譯樣式表是不夠的。這是為什麼 IE7 等許多 patch 方案都是基於運行時而不是預編譯,而我寫的多class兼容方案也是同時需要樣式表預編譯和運行時的 htc 組件。
4. 有許多特性即使預編譯和運行時都用上,也實現不出來,或者性能負擔太高,比如 Shadow DOM 的一些樣式支持,限制非常多,以至於在工程上不實用 —— 因為使用者需要理解太多實現細節,要考慮多種情況下降級後的效果——這樣額外的負擔已經消解了引入這樣方案的目的(不需要太多考慮老瀏覽器)。
儘管如此,這樣的思路仍然值得嘉許。大部分前端碼農苦逼兮兮得搞兼容性好多年,只會罵IE,或者罵標準不實用,卻從來沒有想過工程上類似解決方案的可能性。題主在境界上已經超過了80%的前端。我本人是在看到IE7項目後才脫胎換骨的,題主如果是自己悟出來的,悟性勝過我當年許多!
所以,少年,努力吧!(歡迎投遞簡歷 johnhax at gmail dot com)有啊, Compass/compass · GitHub
當你想要新標準的 CSS 在舊瀏覽器中工作, 就是改變了它的語義, 發明了一種新的語言, 你想要的編譯器和所有這些預處理器沒本質區別, 只是能力更弱而已...
postcss/autoprefixer · GitHub 例如 autoprefixer 其實也是一種預處理器
不過 flex-box 不止是外觀樣式, 還是行為樣式, 不是編譯 CSS 就能解決的
如果不限於編譯 CSS, 有 CSS3 PIE: CSS3 decorations for IE 利用 VML 給 IE polyfill 上部分 CSS3 屬性感覺完全沒有這樣做的必要。老版本的瀏覽器,只要可以實現功能就行了,如果你要通過複雜的預編譯來使它實現新瀏覽器支持的功能。那就跟你說的:
當然這裡會出現一個哲學問題,就是如果你用flex來實現以前用float就可以實現的功能,那要flex還有什麼用呢?
而且實現起來很費勁,比如一個簡單的『border-radius",你要ie7來支持它,只通過css幾乎不可能。然後就要藉助「 CSS3 PIE: CSS3 decorations for IE」這樣的東西,通過vml來畫,且不說性能問題,他還會有很多坑。
而且當你費勁的在低版本瀏覽器上實現了所有效果的時候,用戶升級瀏覽器的慾望也就沒那麼高了了,然後你又要一直費勁的去兼容它。就形成了一個惡性循環。
所以沒有這樣做的必要。現在不都提倡優雅降級嘛,新的瀏覽器儘可能實現更多的效果,老的瀏覽器只要實現功能就可以了。而且,知乎也是這樣做的。用老版本瀏覽器,就意味著用戶喜歡老版本IE那種難看的效果你給顯示好看了,就不符合用戶的預期了那就是BUG
PostCSS的插件CSSNext似乎比較接近你的需求,用未來的寫法兼容現在瀏覽器,cssnext/cssnext · GitHub
一絲女神寫了一個類似的吧 CSS grace@一絲
有時候很難看出你是在做什麼.比如你說的flex...程序如何判斷你寫的flex就是三列等高布局....
況且低版本瀏覽器內核架構不變,即使通過某些技術實現了性能還是很差
記得國內有個人寫過一個類似emmet的東西...輸入簡寫,然後快捷鍵展開.他會同時給你向下兼容的各種方式.....很想深入了解下.但後來找不到了....然後就是回答一下..單純從css看,有時候很難看出你是在做什麼.比如你說的flex...程序如何判斷你寫的flex就是三列等高布局....
我也想過這個問題,然後想像由誰來實現這個轉換的功能最好呢?必須是瀏覽器啊!我只要寫最新的CSS樣式就好,瀏覽器你如果看到了這個新東西,就自動把它轉換成老瀏覽器的老東西來實現一樣一樣的模樣嘛!多麼爽XDDD然後問題來了。。。既然已經是老瀏覽器了,它又要如何擁有這個讓人爽翻的新功能?讓用戶下載個插件加在瀏覽器上?那麼他們為什麼不去下載個最新版本的瀏覽器呢。。。。。。
post css應該和題主說的比較接近
隨著瀏覽器及html5的興起,為了支持舊版本而花費大量時間不是很值得,況且低版本瀏覽器內核架構不變,即使通過某些技術實現了性能還是很差
但是這些工具要麼是用途局限,要麼是效果有限,很難完全達到題主期望的目標
推薦閱讀: