Chrome CSS 2025 年回顧

新聞
HongKong
4
04:42 PM · Jan 05 ,2026

本文由體驗技術團隊申君健原創。

序言

近日發現 Chrome 官方技術平台 chrome.dev 發佈了一篇極具價值的 CSS 技術總結文章,原文鏈接為:CSS-Wrapped-2025,Wrapped 單詞在這裏是打包,總結,回顧的意思。Chrome官方羅列了2025年的新增CSS和組件特性等,有需要的小夥伴可以關注一下。此外,Chrome 官方亦發佈了 2024 年度的 CSS 特性回顧文章,鏈接為:CSS-Wrapped-2024,可以對照查閲。

《CSS Wrapped 2025》一文共分為三個核心章節,分別是可定製的組件(Customizable Components)、 下一代交互(Next-gen Interactions)、 優化的人體工程學(Optimized ergonomics)。 由於精力時間有限,本文先精讀第一部分,有機會再分享後續部分。

2025 全年,Chrome發佈的版本為 132~143,本文的特性也集中在這個範圍,它有很多全新的概念,或者是去年CSS概念的一些延伸。前端人員總不能第一時間使用新特性,以兼容性為藉口忽視新技術,我也是一樣。所以藉此文章中新特性為提綱,全面總結該特性的知識,補充我的一些理解和總結。同時每一個新特性還準備一句話的解釋完整示例,方便大家快速瞭解。Chrome 143升級好了嗎,開始帶你飛!

一、命令調用器 (Invoker Commands)

一句話的解釋

命令調用器是通過Button元素,向Dialog,popover元素或任意元素上觸發一個動作命令。 完整示例

命令調用器特性兼具聲明式語法的高可讀性優勢,且能有效減少 JavaScript 代碼的編寫量。在該特性中,Button 元素被定義為 "命令源",接收命令執行的元素則為 "命令目標"。

命令源:⭐僅 Button 元素才允許當命令源,它添加以下屬性:

  • 【attr】commandfor: 屬性值為命令目標元素的 id,用於關聯對應的命令目標。
  • 【attr】command: 用於指定點擊 Button 元素後觸發的命令動作,其屬性值説明如下:

| 命令 | 行為目標 | 等效js | 備註 | | -------------- | ---------- | --------------------- | ------------------------------------------- | | show-modal | 打開dialog | dialog.showModal() | | | close | 關閉dialog | dialog.close() | | | request-close | 請求關閉dialog | dialog.requestClose() | 可取消: ev.preventDefault() | | show-popover | 打開popover | el.showPopover() | | | hide-popover | 關閉popover | el.hidePopover() | | | toggle-popover | 切換popover | el.togglePopover() | | | --any-command | 自定義命令 | - | 事件名必須 -- 打頭
目標上監聽command事件
非冒泡,可取消的事件 |

  • 【prop】command: 同上
  • 【prop】commandForElement: 同 commandfor ,值為HTMLElement對象。

命令目標: 通常是 dialog, popover元素,為它們添加一個事件:

  • 【event】command: 觸發在目標元素上的事件。 其中事件參數 event.command 是命令值。

兼容性

支持chrome135+ ff144+, polyfill 方案。

總結

  1. 該特性的核心價值不僅在於減少 JavaScript 代碼量,更在於實現了更好的可讀性,更好的語義化,更好的AI識別。Dialog元素是存在較久的冷門標籤,Popover API是近兩年的新特性,之前操作他們必須通過Javascript代碼。
  2. 該特性也是一個微型的通知系統,某些程度上可以代替 new CustomEvent的使用。同樣的,更好的可讀性,參見圖片翻轉的示例。
  3. 命令源只能是Button,某種程度上限制了它的使用。

二、對話框輕量關閉(Dialog Light Dismiss)

一句話的解釋

繼 Popover Api 引入 Light Dismiss 之後,Dialog 也支持了它 完整示例

Light Dismiss 直接翻譯就是輕量關閉,友好關閉,具體是指通過點擊 ::backdrop 區域、按下 Esc 鍵即可觸發目標元素自動關閉的交互行為。Light Dismiss同樣的具備聲明式可閲讀性,還能避免Javascript的使用。

<dialog closedby="none">  不觸發關閉 </dialog>
<dialog closedby="closerequest">接受 esc或其它js觸發 </dialog>
<dialog closedby="any">  接受任何觸發 </dialog>

Light Dismiss 通常是用户在交互過程中預期的默認行為,這一設計不僅體現了 Chrome 對用户使用體驗人體工程學的關注,更彰顯了其對開發者開發體驗人體工程學的重視。開發者無需進行額外開發,即可獲得預期的合理結果。延伸瞭解它的一些細節:

  • closerequest 與 any 的相比,它不接受點擊::backdrop區域關閉;此外移動端的手指側滑或導航回退也會觸發closerequest的行為。
  • dialog.requestClose()在dialog元素上觸發 cancel 和 close事件, 而dialog.close() 只觸發close事件。 在cancel事件中執行ev.preventDefault()可阻止關閉。
  • dialog元素沒有open事件,但它有 toggle, beforetoggle事件, 用來監聽打開關閉。 事件對象的oldState,newState用來判斷切換的方向。 此外,只有dialog 和 彈出層支持這2個事件名。

兼容性

支持chrome134+ ff141+, polyfill 方案。

延伸理解 Popover API 的Light Dismiss

<button popovertarget="mypopover" popovertargetaction="toggle">切換顯示</button>
<div id="mypopover" popover>這是一個 auto 彈出層</div>

命令源:⭐僅 Button 元素和Input(type=button)才允許當命令源,它添加以下屬性:

  • 【attr】popovertarget: 其值為popover元素id
  • 【attr】popovertargetaction: 點擊的命令動作,其值為: 'hide' | 'show' | 'toggle'

觸發popover還可以用傳統的Javascript, 或者Button的commands 模式,比如: el.showPopover()

popover層: 任意添加了 [popover] 屬性的元素

  • 【attr】popover: 設置元素為一個彈出層,它最早支持以下2個值:
    • auto: 自動模式,也是默認值。 auto即符合Light Dismiss默認關閉行為。同一個頁面上,auto類別的元素只能顯示一個。
    • manual: 手動模式。必須顯示的聲明popovertargetaction,或調用Javascript函數才觸發,比如:el.showPopover()。同一個頁面上,manual類別元素可顯示多個。

參考完整示例,對比 Dialog 與 Popover API :

  • 都支持Invoker Commands 和 Light Dismiss
  • 都支持Javascript控制和聲明式表達: dialog元素的closedby 和 popover元素的popover屬性
  • 都會產生一個Top Layer, 無須z-index就能置頂元素,且不受父元素的position影響。
  • 命令源和命令目標之間會隱式的產生aria-details關聯aria-expanded,用於觸發焦點導航等。

Popover API的這些特性兼容性為:chrome114+, ff125+

三、增強Popover (popover="hint") 與 興趣調用(Interest Invoker)

一句話的解釋

hint暗示:一種更輕量的觸發行為的popover類別 完整示例

在上小節中,已經講了popover原有的2個類別,今年它又新增了一個類別:hint 暗示。這種hint彈出層,不僅可以用原來的方法觸發它,還增加了一種興趣調用觸發。 興趣調用Interest Invoker是指:通過非點擊事件,比如hover,mouseover,mouseout, focus,blur 它的變化。懸浮就顯示,離開就隱藏,十分符合tooltip組件場景。

  <button interestfor="mypopover1">懸浮觸發 hint1 彈出層</button>
  <div id="mypopover1" popover='hint'>這是一個 hint1 彈出層</div>

命令源:它新增以下相關內容:

  • 【attr】interestfor: 屬性值為 hint類別的popover元素id
  • 【css-rule】interest-delay: 設置懸浮觸發和離開隱藏的時間。 它是複合屬性: interest-delay-start, interest-delay-end。默認觸發的時間是 0.5s。
  • 【css-selector】 :interest-source 和 :interest-target 是指,如果當前興趣正在發生,那麼觸發源和hint 彈出層就分別為具有上面的偽類。類似於 dialog打開時,dialog:open的偽類一樣。詳見上面示例。

hint 彈出層:新增以下事件:

  • 【event】interest: 觸發顯示的InterestEvent事件, 事件的source指向觸發源元素。
  • 【event】loseinterest: 離開失去的InterestEvent事件,事件的source指向觸發源元素。

興趣調用與前面2節的內容有一些重要的差異:

  1. 強調必須非點擊事件,場景對應"懸而未決"的狀態,可以配合popover="hint"使用。
  2. 觸發源更廣泛,不僅是Button元素,還允許 <a>, <button>,<area>,SVG <a>
  3. hint類別不影響auto類別的彈窗,不會主動觸發auto彈窗關閉。

長期以來Web標準對hover行為是淡視的,只有title屬性和 :hover的偽類,一直缺少關鍵的hover事件。此次提供 interest事件,藉此可以變相的視為一種hover事件

兼容性

支持chrome 142+, 不支持:ff,safari, polyfill 方案。

四、可自定義的select (Customizable select)

一句話的解釋

增強的select 和 option 元素,豐富的偽類、偽元素,定製更容易 完整示例

可定製的select增加了很多dom規範和偽類,偽元素,內容太多不宜展開細述,感興趣看上面的完整MDN示例,我已經增加詳細的註釋。此處僅列出一些重要的概念和事項,以便能快速理解:

  1. base-select 設置:

select 和 ::picker(select)偽元素都必須添加規則: appearance: base-select ,以區別於傳統select樣式。

  1. 彈出層::picker(select)特性:

它渲染在頁面頂層Top Layer,這意味着它會顯示在所有其他內容之上,不會被父容器裁剪。瀏覽器還會根據視口中的可用空間自動調整下拉列表的位置和翻轉。

  1. 增強的option:

傳統的option元素僅支持 label,value屬性和selected,disabled的布爾屬性。option中嵌套有其它元素,都是會忽略的

增強後的option元素支持嵌套span,img等等普通元素,但要避免嵌套 a, input 等交互元素就行了。

  1. 新增 selectedcontent 元素:

該元素必須遵循 select > button > selectedcontent 的嵌套結構,詳見示例。

select的選擇值(即change事件)之後,選中的option的節點會被cloneNode創建副本,插入到selectedcontent中,所以他們結構一樣,但不是同一個元素實例。

同時button是惰性的,不響應focus等,行為更像是 div

option 和 selectedcontent 的子項,都可以用普通的 css 選擇器去分別控制樣式。

  1. select 借用 Popover API

隱式借用了非常多的Popover 特性,比如 :popover-open偽類,無需anchor-name的隱式的錨點引用,且可以定義彈出層與錨點的位置關係,溢出翻轉等等。

  1. select的multiple 和 optgroup 未增強

這意味着多選和分組功能,需要重新實現,對於組件庫的作者來説,這無疑得回退到傳統方案,幸好有Popover API。

兼容性:

支持 chrome 135+ , ff,safari均 不支持😭,polyfill 方案

這個方案並非真正意義的polyfill, 它使用自定義的 webComponent技術實現了平替。

五、滾動控制偽元素(::scroll-marker/button())

一句話的解釋

為滾動容器的添加偽元素,用於控制容器滾動 完整示例

HTML早早添加了dialog, detail 等元素,但一直沒有增加一個輪播圖元素,今年只摳摳搜搜添加了三個偽元素,或許是因為添加一個新元素需要考慮的事情太多。

  1. ::scroll-button() 滾動容器按鈕的偽元素,點擊它會觸發容器滾動。它非常類似於 ::before, ::after作用, 都需要content才顯示,且呈現在容器的內部。

每個容器最多有4個滾動方向,括號的作用是指定滾動方向,可取值:*, left,right,up,down, block-end,block-start, inline-end,inline-start等。

按鈕偽元素具有狀態,比如容器滾動到兩端之後,滾動按鈕會自動禁用。 它具有以下狀態: enabled, disabled,hover,active,focus

  1. ::scroll-marker 是滾動容器中,指示滾動項的偽元素,它同樣也需要content才顯示。

它具有 :target-current 偽類, 表示滾動到當前滾動項。當然, :hover, :active等偽類也能使用

  1. ::scroll-marker-group 是呈現在滾動容器內部的偽元素,收集容納所有的::scroll-marker元素。

marker-group元素自身沒有高度,但可以設置邊框,佈局,間距等內容。

兼容性:

支持chrome 135+ , ff,safari均 不支持😭。由於它是css 特性,無法Polyfill, 建議使用傳統的div去實現即可!

六、設置滾動標記組容器(scroll-target-group)

一句話的解釋

設置元素為滾動容器 完整示例

CSS屬性 scroll-target-group 用來指定一個元素為滾動標記組容器, 它只有2個值:

  • none: 元素非滾動標記組容器
  • auto: 元素為滾動標記組容器

滾動標記組容器中通常包含錨點鏈接列表等,配合偽類 :target-current 來突出顯示某個錨點,效果非常類似傳統的Anchor組件,當容器滾動時,可以高亮指定的目錄項,不過這些都是瀏覽器自動完成的,不需要一行javascript。

它與::scroll-marker-group 有某些相似點:

  • ::scroll-marker-group:是在某個元素內部,創建一個偽元素容器,用來容納::sroll-marker, 都是偽元素。
  • scroll-target-group: 是把一個真實元素變為滾動容器,內部放真實的link 類元素,所以控制上會更靈活。

從官方的態度看,這2個概念極其相近,都是定義了一個滾動容器,且內部的錨點行為一致,均支持偽類 :target-current 代表高亮狀態,避免Javascript去滾動和設置高亮等。

兼容性:

支持 chrome 140+ ,但ff,safari均 不支持😭,且css 特性無法Polyfill。

七、錨定容器查詢(Anchored Container Queries)

一句話的解釋

錨點定位時,翻轉狀態可以查詢完整示例

2024年的CSS回顧中,介紹了CSS錨點定位------- anchor positioning, 實現類似 Tooltip組件的效果,讓一個彈出層錨定到目標元素周圍,且能自動翻轉到適合位置,避免使用Javascript。 它的兼容性: chrome125+, safari26+, ff 不支持。

下面例子演示了:CSS錨點定位。tooltip會錨定在button的上下, 當滾動到邊界時,會自動翻轉顯示。

.my-button {
  anchor-name: --my-btn-anchor; /* 定義一個名為 --my-btn-anchor 的錨點 */
}

.my-tooltip {
  position: absolute; /* 或 fixed */
  position-anchor: --my-btn-anchor; /* 關聯到上面定義的錨點 */
  position-area: bottom;
  position-try-fallbacks: flip-block; 
}

思考一個問題:如果my-tooltip元素有小三角指示方向,那麼簡單的翻轉後,小三角的位置怎麼旋轉呢? 答案是:定位元素無法意識(be aware)狀態,小三角方向會錯誤。

此問題的解決方案即本次新增了CSS錨定容器查詢能力,它通過指定tooltip的 container-type: anchored, 然後使用@container anchored 的查詢語法,就讓tooltip查詢到,意識到自身的翻轉狀態(fallbacks 狀態)。

.tooltip {
  container-type: anchored;

  /* 默認在下方, 小三角向上,位置在底部 */
  &::before {
    content: '▲';
    position: absolute;
    bottom: 100%;  
  }
}
/** 當容器查詢到錨點變化 */
@container anchored(fallback: flip-block) {
  .tooltip::before {
    /* 小三角向下,並移到到頂部 */
    content: '▼';
    bottom: auto;
    top: 100%;  
  }
}

要講明白錨點定位需要很大篇幅,且該示例複雜,大家可以轉到官網查看示例。 目前 container-type: anchored 的文檔連MDN上都沒有,是比較新的概念。

container-type有效值:

  • normal: 元素不支持任何查詢
  • size: 支持 inline 和 block 元素的尺寸的高度和寬度查詢
  • inline-size: 僅支持 inline 元素的尺寸的寬度查詢
  • scroll-state: 支持滾動態的偏移量和是否滾動到底等查詢,chrome 133+, 但ff,safari均不支持
  • anchored: 錨點查詢

兼容性:

container-type: anchored 支持 chrome 143+ ,但ff,safari均不支持😭,且css 特性無法Polyfill。

總結

通過以上種種新特性,可以看出chrome 不僅關注使用用户體驗,更關注開發者體驗。通過增加類似command屬性,或者Light Dismiss的默認行為,以及滾動容器,滾動容器偽元素等技巧,讓許多場景都可以無Javascript實現了。 不僅大大減少開發代碼,還有極強的DOM可讀性。

我目前從事於組件庫開發。在組件庫的開發時,所採用的技術通常是落後於瀏覽器最新技術的,理由就是為了兼容用户瀏覽器。比如 dialog 元素已經是廣泛兼容,但目前仍沒有見到哪個組件庫使用它。通過這次梳理技術,感覺藉助 dialog 以及 popover api 可以極大簡化以往的組件開發,諸如:監聽按鍵,計算z-index,計算彈出層位置,監聽滾動進行位置跟隨等等,這些是問題bug集中爆發區,現在基本都可以無Js代碼的實現了。

另外,前面的諸多未廣泛兼容的技術,大都有相應的Polyfill,尤其是屬性,函數和事件的Polyfill基本都能找到。CSS的新偽類,偽元素雖然很難有Polyfill,但可以用添加類名的方案來兼容,輔助以一些Js事件就可以實現某種程度上的polyfill。oddbird.tech是一家服務公司,得到過Google的贊助,它們一直關注開發Popover APIAnchor positioning的兼容方案。這些方案都讓我們以及早的使用新技術進行開發。

如果只需要支持最新的瀏覽器,前端的春天來了!

關於OpenTiny

歡迎加入 OpenTiny 開源社區。添加微信小助手:opentiny-official 一起參與交流前端技術~

OpenTiny 官網:https://opentiny.design

OpenTiny 代碼倉庫:https://github.com/opentiny

TinyVue 源碼:https://github.com/opentiny/tiny-vue

TinyEngine 源碼: https://github.com/opentiny/tiny-engine

歡迎進入代碼倉庫 Star🌟TinyEngine、TinyVue、TinyNG、TinyCLI、TinyEditor~ 如果你也想要共建,可以進入代碼倉庫,找到 good first issue 標籤,一起參與開源貢獻~

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.