Houdini也許是你從未聽過的在CSS領域最令人興奮的發展

      網友投稿 879 2025-04-02

      前言

      這一篇我來晚了。。不過這篇文章看就對了,早讀君也是在節前看到的Houdini這個單詞,焦慮中。

      正文從這開始~

      你是否曾經試過想使用某個CSS特性但是卻因為他沒有被所有瀏覽器支持而不能用?又或者更糟糕的,他被全部瀏覽器支持,但是這種支持充滿了bug、表現不一致甚至是不完全兼容的?如果這些事情曾經在你身上發生過——并且我打賭他們絕對發生過——那么你就需要關注一下Houdini。

      Houdini是一個新的W3C工作組,他們致力于讓這些問題永遠消失。他們計劃通過引入一整套API來讓開發者首次擁有擴展CSS的權利,并且會提供出一套工具來與瀏覽器的渲染引擎的樣式與布局進行掛鉤。

      但是這意味著什么呢?這是一個好的提議嗎?這會如何幫助我們開發者在現今與未來構建網頁呢?

      在這篇文章里,我將嘗試去回答這些問題。但是在我回答之前,弄清楚今天我們遇到了什么問題和為什么需要這樣的變革是很重要的。然后我會更詳盡地去解釋Houdini如何去解決這些問題,并且列出一些在現今開發上十分令人振奮的特征。最后,我會提供一些具體的,我們的開發者現在可以去完成的事情來讓Houdini變成現實。

      Houdini嘗試解決什么問題呢

      每次我為一些全新的CSS特征編寫文章或者構建一個demo,必然會有人在評論或者推特上說,“這真的很棒!不過我們可能未來十年都不會用到它們。”

      像這些煩人且毫無建設性的評論,我可以理解那種情緒。從歷史上來看,一個功能建議要花費數年才能被廣泛使用。其原因在于,縱觀整個web的歷史,唯一能讓一個新特征加入CSS的方法就是走完整個標準過程。

      當然我不是反對標準過程,但是不可否認的是他花費太多時間了。

      例如,flexbox在2009年第一次被提出,然而直至今天,開發者仍然抱怨因為缺乏瀏覽器的支持而不能使用它。當然,這個問題正在慢慢的被解決因為現在幾乎所有現代瀏覽器都會自動更新;但是即使是現代瀏覽器,從功能提議到全面上市仍然會有延遲。

      有趣的是,并不是所有web的領域都是這樣。看一下在JavaScript上事情最近是怎么發生的:

      在這種情況下,可能只需要花費幾天就能把一個想法運用到生產中去。我的意思是,我已經在生產中使用async/await了,但是這個功能仍然未被加入到任何一個瀏覽器中。

      你還可以看到這兩個社區的普遍情緒上的巨大差異。在JavaScript社區,你會閱讀到人們抱怨變化太快的文章。而在CSS社區,相反你聽到的是人們哀嘆學習新東西的徒勞因為他們不知道什么時候才能使用他們。

      所以為什么我們不編寫更多的CSSPolyfills呢?

      第一個想法就是,編寫更多CSSpolyfills似乎是解決問題的方法。如果有了良好的polyfills,CSS就可以像JavaScript那樣快速前進了,不是嗎?

      然后悲傷的是,并沒有那么簡單。對CSS進行polyfill是難以置信的困難,大部分情況下,你不能在完全不破壞性能的情況下去完成polyfill。

      JavaScript是一個動態語言,這意味著你可以使用JavaScript來polyfill JavaScript。又因為他是動態的,所以他特別容易被拓展。反之,CSS很難被用來polyfill CSS。某些情況下,你可以在編譯步驟里面轉化編譯CSS(PostCSS負責這種工作);但是如果你想polyfill任何基于DOM結構的或者是元素布局位置的屬性,你必須要在客戶端運行你的polyfill邏輯。

      不幸的是,在瀏覽器上完成這項任務并不容易。

      下圖勾勒出了你的瀏覽器如何把一個HTML文件展現到屏幕上的過程。用藍色標注的部分是JavaScript有權利控制的部分:

      圖片顯示的結果相當慘淡。作為一個開發者,你并不能控制你的瀏覽器如何解析HTML和CSS也不能控制他如何把HTML和CSS轉化成DOM和CSS對象模型(CSSOM)。你無法控制級聯。你無法掌控瀏覽器如何在DOM里布局元素,如何在屏幕上繪制元素。你也無法控制合成器。

      唯一一個你可以全部控制的進程就是DOM。CSSOM部分開放;然而,引述自Houdini的網站,這種開放是“尚未被確認的,在瀏覽器上是不一致的,并且缺少關鍵功能。”

      例如,如今的瀏覽器的CSSOM不會展示你的跨域樣式表,而且他會輕易丟棄掉任何他不認識的CSS規則或者聲明,這意味著如果你想polyfill一個瀏覽器尚不支持的功能,你不能使用CSSOM。相反,你必須通過DOM,找到and/or標記,拿到CSS樣式,解析、重寫再把它添加到DOM上。

      當然,更新DOM通常意味著整個瀏覽器必須重新完成所有的級聯、布局、繪制和合成的步驟。

      盡管完全重繪一個頁面對性能的影響看起來并不會特別大(特別是某些網站),但是思考一下這種事情發生的頻率。如果你的polyfill邏輯是需要對滾動事件、窗口大小調整、鼠標動作、鍵盤事件進行響應的話——基本相當于任何時候都在改變——那么事情將會十分明顯,有的時候甚至是接近極限,十分緩慢。

      當你意識到今天絕大部分的CSSpolyfill包含他們自己的CSS解析器和他們自己的級聯邏輯,你會發現狀況變得更加的糟糕。又因為解析和級聯都是十分復雜的事情,這些polyfills通常不是太大就是充滿了bug。

      簡單的總結一下剛才我所說的:如果你想讓你的瀏覽器(因為你給予的CSS)做一些它自身不支持的事情,那么你必須要親自通過更新和修改DOM來偽造出這種效果。你在其余的渲染步驟里沒有權限。

      但是為什么我會想改變瀏覽器的內部渲染引擎呢?

      這對于我來說,絕對是整篇文章中最重要的問題。所以如果你一直都是快速瀏覽的話,這部分必須緩慢而且仔細的閱讀!

      在看到最后一節后,我相信部分人會認為“我不需要這些!我只是想構建一個正常的網頁。我并不想侵入我的瀏覽器內部去創造一些十分花哨的、試驗性的甚至可能會造成問題的效果。”

      正常化瀏覽器之間的差異

      發明并且polyfill一些新功能讓人們可以使用。

      如果你曾經使用一些JavaScript庫諸如jQuery,那么你會從這種能力里面獲益良多!事實上,這是現今幾乎所有前端庫或者框架的主要賣點。五個Github上面最流行的JavaScript和DOM資料庫——AngularJS, D3, jQuery, React和Ember——都在減少跨瀏覽器間的差異上做了很多工作所以你不用去考慮他們。他們都只暴露出一個API,然后這個API正常工作。

      現在,回想一下CSS和他那些跨瀏覽器問題。即使是最流行的CSS框架如Bootstrap和Foundation,盡管他們生成自己具有跨平臺的兼容性,但是他們并沒有消除跨瀏覽器的bug——他們只是避免觸發bug的做法。而CSS跨瀏覽器bug并不僅僅是過去的問題。甚至在擁有新的布局模式的如flexbox的今天,我們仍然會面對很多跨瀏覽器不兼容的問題。

      底線是,想像一下如果你可以使用任何CSS屬性,并且知道他們一定會生效,在每個瀏覽器里面表現都是一樣,那么你的開發工作會變得多輕松。再想象一下,你在其他blog文章上面或者在會議上知道的新特性——如CSS grids,?CSS snap points和stickypositioning。如果你今天就可以使用它們并且它們的性能表現的就像原生的CSS功能一樣。而你所有需要做的就是從Github上面獲取代碼。

      這就是Houdini的夢想。這就是他們期望的未來。

      所以,即使你并不打算去寫一個CSSpolyfill或者開發一個實驗性的功能,你可能會想讓其他人可以這么做——因為一旦這些polyfill存在,每個人都可以從中獲益。

      Houdini有什么功能正在被研發中呢?

      我在上面提到開發者對于瀏覽器的渲染過程沒有什么控制權。事實上,唯一可以控制的是DOM并且一部分的CSSOM。

      為了解決這個問題,Houdini工作組引入了幾個新規范。這將會首次讓開發者對渲染過程里的其他部分擁有訪問的權利。下表展示了在新規范中渲染過程哪部分可以被修改。(注意灰色的規范是在計劃中但是尚未被編寫。)

      下面幾個部分將會簡短地瀏覽一下每一個新規范,介紹他們提供了什么。我應該注意到在這篇文章中有另外一個規范未被提及;你可以從GitHubrepository of Houdini’s drafts上面觀看完整的列表。

      CSS解析器API

      CSS解析器API尚未被編寫;所以我所說的大部分都很容易被改變。但是基本想法是讓開發者拓展CSS解析器并且告知他們新的結構——例如新的媒體規則、新的偽類、嵌套、@extends、@apply等等。

      一旦解析器知道這些新的結構,它就可以把它們放到CSSOM里面的正確位置上去,而不是拋棄掉他們。

      CSS屬性和值API

      CSS已經具有自定義屬性了,就像我之前提到的那樣,我對他們被解開的可能性感到十分興奮。而CSS屬性和值API則在自定義屬性上更進一步,通過添加類型讓他變得更加有用。

      在自定義屬性上添加類型會帶來很多好處,不過最大的賣點或許就是這些類型會讓開發者可以為自定義屬性添加transition和animate這些我們今天不能使用的功能。

      看一下以下例子:

      在上面的代碼中,如果night-theme類別添加到`元素上,頁面上每個具有--primary-theme-color屬性的元素的值都會慢慢的從tomato轉變成darkred`。如果你想在今天完成這些,你必須要手動地為每個元素寫transition,因為你不能對自定義屬性進行transition變換。

      這個API另一個十分有希望的特點是可以注冊一個“應用鉤”(apply hook),這讓開發者可以在級聯步驟完成后仍然可以修改一個自定義屬性的值,這對于polyfill可能是一個十分有用的功能。

      CSS Typed OM

      CSS Typed OM可以被認為是現在使用的CSSOM的第二個版本。他的目標是解決很多現有模型的問題并且會引入新的CSS解析器API和CSS屬性和值API的特性。

      Typed OM的另一個主要目標是改進性能。將當前CSSOM的字符串值轉化成有意義的類型化的JavaScript表達式會產生顯著的性能提升。

      CSS布局API

      CSS布局API讓開發者可以編寫他們自己的模型。通過“布局模型”,基本上所有東西都能被傳入到CSSdisplay屬性中。這會讓開發者第一次可以像原生的布局模型display:flex和display:table那樣高效地進行布局。

      作為一個示例,Masonry布局庫展示了開發者開發者有多愿意去完成僅依靠CSS無法搭建的布局。盡管這些布局令人印象深刻,但是不幸的是,他們充滿了性能問題,特別是那些不那么強勁的設備上。

      CSS布局API會給予開發者一個registerLayout方法來接受布局名稱(這在稍后的會被用到)和一個JavaScript類來引入所有布局邏輯。下面是一個基本例子告訴你如何通過registerLayour來定義masonry:

      如果你看不懂上面的例子,不要擔心。主要需要關心的是下面的代碼。一旦你下載了masonry.js文件,并且將它添加到你的網站上,你可以像下面那樣編寫CSS然后他們就會工作:

      CSS繪制API

      CSS繪制API和上面的布局API十分相似。它提供了一個registerPatint方法,操作方式和registerLayout方法一樣。開發者然后可以在CSS中任何地方需要CSS圖像的地方使用paint()函數,只要傳入他們注冊的名稱就好。

      下面是一個簡單繪制有顏色的圓的例子:

      在CSS中它可以這樣使用

      現在,.bubble元素會展示一個藍色的圓形作為背景。圓形自身會被放置在中間,并且大小回合元素本身一樣,無論發生什么事。

      Worklets

      上面列舉的許多規范都展示了代碼示例(例如,registarLayout和registerPaint)。如果你好奇你應該在哪里放置這些代碼,答案就是worklet腳本。

      Worklets和web workers十分相似,他們都允許你引入腳本文件并且運行JavaScript代碼。而且他可以在渲染過程中的不同地方被調用,并且獨立于主線程。

      Worklet腳本會為了保證高性能嚴重限制你可以用的操作類型。

      合成滾動和動畫

      盡管仍然沒有官方的合成滾動和動畫規范,這仍然是實際上比較知名和高度受關注的Houdini功能。最終的API會允許開發者在合成worklet中執行邏輯運算,而且這是獨立于主線程的,可以去修改一些指定的DOM元素屬性。這些屬性只會是那些可以在不需要重繪的情況下進行更改的屬性。(如transform、opacity、scroll offset)。

      這會讓開發者可以創造高效的滾動動畫或者基于輸入的動畫,如粘滾動的標題和時差效果。你可以在Github上掛看更多這個API嘗試去解決的樣例。

      盡管尚未有官方的文檔,Chrome上已經開始了實驗性的開發。事實上,Chrome團隊正在使用這個API最終會暴露的方法來添加CSS捕捉點(CSS snappoints)和粘定位(stickypositioning)。這是十分驚人的,因為這意味著Houdini的API足夠高效,以至于新的Chrome特性依據他們來構建。如果你仍然害怕Houdini不如原生的快,這個事實會說服你。

      Surma錄制了一個在Chrome上運行視頻樣例。這個demo模仿了Twitter原生移動應用的滾動標題欣慰。可以點擊源碼查看他是怎么工作的。

      你現在可以做什么?

      就像我之前提到的那樣,我認為每個網站構建的人都應該關注Houdini;他將會在未來讓我們生活的更加方便。即時你從來沒有直接使用過Houdini規范,你也必然會使用一些基于他們完成的模塊。

      盡管這個未來不是馬上就到來,但是他會比很多人想象想的要接近。所有的主要瀏覽器廠商都參加了今年稍早時候悉尼舉辦的最新Houdini面對面會議。他們對于要做什么如何構建這些問題產生的分歧還是比較少。

      我認為的是,問題不是Houdini會否被實現,而是什么時候被實現。這也是需要你們的地方。

      瀏覽器廠商,就像軟件開發商一樣,會對新功能進行分級。而這些優先級則一般都是用戶對其的渴望程度。

      所以,如果你關注web上面的樣式和布局的拓展性。如果你希望以后你可以不用等待漫長標準過程就能使用新的CSS功能。那么就和你使用的瀏覽器的開發者們說,告訴他們你想要這個功能。

      另一種幫忙的方法就是提供現實中的用例。那些你現在很難通過樣式和布局實現的效果。有些Github上的草稿都有用例文檔,你可以提交一個pull request來貢獻你的想法。如果文檔不存在,你可以創造一個。

      Houdini工作組(和W3C一樣)十分希望得到web開發者的建議。許多參加規范編寫的人員都是瀏覽器開發工程師。他們自身不是專業的web開發者,這意味著他們通常不知道痛點何在。

      這需要我們去告訴他們。

      資源鏈接

      CSS-TAG Houdini Editor Drafts,W3C

      最新的Houdini公開的草稿版本。

      CSS-TAG Houdini Task ForceSpecifications, GitHub

      規范更新和開發的官方Github資料庫。

      Houdini Samples, GitHub

      代碼樣例展示和利用可能的API進行的實驗。

      Houdinimailing list, W3C

      問問題的地方。

      后語

      看到這個,早讀君有個問題了,大家一般都從哪里看最新的前端資訊,有的話分享分享。文中提到的資源鏈接,大家可以查看原文~

      關于本文

      譯者:@李猜猜

      原文:http://www.w3ctech.com/topic/1735

      本文轉載自異步社區

      Houdini:也許是你從未聽過的在CSS領域最令人興奮的發展

      云搜索服務 CSS API

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:怎么一下全刪除頁眉頁腳(如何刪掉所有頁眉頁腳)
      下一篇:WPS表格2013中新建表格樣式的方法(wpsword新建表格樣式)
      相關文章
      国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 亚洲精品无码久久毛片| 亚洲av产在线精品亚洲第一站| 亚洲国产日韩女人aaaaaa毛片在线| 精品久久香蕉国产线看观看亚洲| 亚洲av成人一区二区三区观看在线| 亚洲国产成人精品激情| 久久国产亚洲观看| 亚洲无av在线中文字幕| 亚洲色偷偷综合亚洲AVYP| 337P日本欧洲亚洲大胆艺术图| 亚洲av永久无码天堂网| 亚洲AV无码一区二区三区网址 | 亚洲国产AV一区二区三区四区 | 国产成A人亚洲精V品无码| 亚洲精品蜜桃久久久久久| 亚洲人成亚洲人成在线观看| 亚洲熟妇丰满多毛XXXX| 九月丁香婷婷亚洲综合色| 亚洲AV成人一区二区三区AV| 亚洲伊人久久大香线蕉苏妲己| 91亚洲导航深夜福利| 亚洲国产成人91精品| 亚洲制服丝袜一区二区三区| 亚洲一区中文字幕在线观看| 色天使亚洲综合在线观看| 亚洲av无一区二区三区| 亚洲 无码 在线 专区| 爱情岛论坛网亚洲品质自拍| 亚洲三区在线观看无套内射| 亚洲av伊人久久综合密臀性色| 亚洲国产女人aaa毛片在线| 亚洲精品熟女国产| 亚洲熟妇av午夜无码不卡| 国产精品亚洲а∨无码播放不卡| 亚洲性日韩精品一区二区三区| 亚洲日韩精品无码专区网址| 亚洲A∨无码一区二区三区| 亚洲成人午夜电影| 亚洲精品无码aⅴ中文字幕蜜桃| 成a人片亚洲日本久久|