HTML 也一直在高速發展,今天我們一起來看看 HTML 最近有哪些值得關注的新特性。
可以定制樣式的下拉菜單
瀏覽器為了保持向后兼容性,并不會貿然改變像 <select>
和 <option>
這些元素的樣式。這時候,一個巧妙的引入便是“選擇加入”機制,它讓開發者在可控的情況下,自由施展創意。起初,大家期待的解決方案是新元素 <selectmenu>
,但它在漸進增強的表現上并不理想。最終,CSS 提供了一種更加靈活的方法:
select,
::picker(select) {
appearance: base-select;
}
這種新方式讓 <select>
的內嵌元素能夠獲得更為自由的樣式定義,為我們打開了設計選擇控件的新大門。例如,現在你可以在 <select>
中插入按鈕和圖像,從而創造出更視覺化的用戶選擇體驗:
<select class="country-select">
<button>
<selectedoption></selectedoption>
</button>
<option value="" hidden>
<figure></figure>
<span>選擇一個國家</span>
</option>
<option value="andorra">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Andorra.svg/120px-Flag_of_Andorra.svg.png" alt="" />
<span>安道爾</span>
</option>
<!-- 更多選項 -->
</select>
可以增加分割線的下拉菜單
講到 HTML 的老派元素,它們總是能以意想不到的方式令人耳目一新。就像我們熟悉的 <details>
元素通過 name
屬性能實現手風琴效果一樣經典。在 <select>
菜單中,你也可以用 <hr>
元素來增加一條簡單的橫線。
這聽起來是不是很酷?最初我們可能習慣通過 <optgroup label="組名">
來進行分組,不過在一些場景中,簡單直接的一條線反而能更好地表達層次感和視覺分隔。
比如看下面這個例子:
<select>
<option>蘋果</option>
<option>橙子</option>
<option>香蕉</option>
<hr>
<option>辣椒</option>
<option>西葫蘆</option>
<option>西蘭花</option>
</select>
這條線安靜地躺在菜單中,中規中矩,卻直觀地將水果與蔬菜分隔開。這樣的設計方法無需復雜的代碼,卻足以為 UI 增添別樣的細節,簡約而不簡單。
直接用操控 Popover
現在,你可以使用按鈕輕松開啟或關閉一個 Popover
,無需編寫一行 JavaScript
代碼。這為網頁交互提供了更為直觀的操作方式。
示例:
<button popovertarget="the-popover">打開 Popover</button>
<div popover id="the-popover">
你好 code秘密花園
<button popovertarget="the-popover">關閉 Popover</button>
</div>
如果你希望用戶只需點擊 Popover
外部任意位置即可關閉它,那么只需將 popover
屬性改為 popover="auto"
即可,這種交互方式通常被稱為“輕量級消失”。
這些與按鈕關聯的目標行為,被稱為“調用者(Invoker
)”,預示著在未來幾年 HTML 將獲得更強大的功能。
雖然 Popover 不能像 <dialog>
那樣通過表單提交來關閉,但考慮到 Popover 并不是適合放入表單的地方,這點限制反而顯得無關緊要。一個有趣的小細節是,你可以將 <dialog>
設為 Popover,從而輕松獲得這種按鈕操作。
雖然對話框與 Popover 各有差異,但都非常實用。也許它們最重要的兩個特性是:它們擁有的焦點限制能力,以及它們被提升到網站渲染的“頂層”,使得無需煩惱 z-index 的調整。
目前,Popover 的位置定位基本上局限于居中或邊緣,像對話框一樣,還不支持錨點定位。但這種能力預計在 2026 年將實現跨瀏覽器的兼容。
Checkbox 輕松變身 Toggle
復選框迎來了全新的可能性 — 它們可以在不費吹灰之力的情況下變身為 Toggle
開關。你只需簡單地使用一個屬性:
<input type="checkbox" switch>
目前這一特性僅在 Safari
瀏覽器中有效,而且尚未有正式的規范。
使用 <search>
簡化搜索
在網頁設計中,許多人可能曾一度忘記為搜索區域正確地添加角色屬性,或者發現使用 <div role="search">
不夠直觀。現在,HTML 提供了一種更加直接的方法:使用 <search>
標簽。
<search>
<!-- 你的搜索表單或組件 -->
</search>
這個小小的標簽為開發者提供了一種更簡潔、易記的方式來標記頁面中的搜索區域。不再需要額外的角色屬性,只需簡單地將搜索相關的內容包裹在 <search>
標簽內,即可保證語義的明確性。
不再需要 noopener noreferrer
在過去的一段時間里,開發者們往往會在使用 _blank
打開新頁面的鏈接中添加 rel="noopener noreferrer"
屬性。這種做法主要是為了防患于未然,避免在新開頁面中可能出現的安全問題,比如泄露引用者信息或被釣魚攻擊。
<a
href="https://conardLi.top"
target="_blank"
rel="noopener noreferrer"
>
但你或許不知道,自從 2021 年開始,主流瀏覽器(其中最后一個是 Chrome)已經自動為 _blank
鏈接應用該行為,這意味著這種手動添加的方式在很多情況下已經不再必要。
我個人在項目中也曾因使用代碼檢查工具(linter)而被時常提醒,繼續保持這樣的代碼習慣。為了確保代碼的安全性和兼容性,我們有必要定期審視這些工具的配置,并根據當前的瀏覽器支持情況進行相應調整。別再為過去的做法感到拘謹,可以在確保安全的情況下,清理那些不再需要的冗余代碼,讓項目更加簡潔高效。
聲明式 Shadow DOM
在 Web 組件的發展歷程中,過去要想使用 Shadow DOM
,只能依賴 JavaScript
渲染。這種實現方式讓使用 Shadow DOM
的 Web
組件在服務器端渲染(SSR)上寸步難行,形成了一個關鍵性短板。然而,所有主要的 UI 框架都越來越重視 SSR,因為它能顯著提高性能、加載速度、SEO 以及增強網頁的彈性。
隨著聲明式 Shadow DOM
的出現,這一局限被打破。現在,開發者可以實現完全不依賴 JavaScript
的 Shadow DOM
應用。
聲明式 Shadow DOM 被視作一種基礎工具,更多時候將由庫或框架來封裝使用,以提升開發者的體驗,而非手動書寫。
過去,React 19
是最后一個完整支持 Web 組件的框架。未來,我們可能會看到框架不僅僅是支持 Web 組件,而是全面接受和擁抱它們。也許不久的將來,一個類似于 Next.js 的 Web 組件框架將應運而生。
Import Maps 導入模塊
在 JavaScript 開發中,我們習慣了用這樣的方式來導入模塊:
import React from "react";
乍一看,這似乎是 ES 模塊的代碼。但如果你仔細觀察,會發現字符串里的路徑既不是絕對 URL,也不是相對路徑。我們只是習慣這么寫,因為 JavaScript 打包工具會識別它為 npm 包,并自動從 node_modules
文件夾中查找。
然而,如今情況發生了變化。通過 HTML 的 Import Maps,我們可以將諸如 "react"
這樣的值映射到實際的 URL 上,從而直接在瀏覽器中導入。
舉個例子,如果你從一個包含如下 Import Map 的 HTML 文件中執行上述 JavaScript:
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@18",
"reactdom": "https://esm.sh/react-dom@18"
}
}
</script>
那么,這段代碼將能夠從指定的位置導入 React 和 React DOM,而不需要借助打包工具。這樣一來,即使省去繁雜的工具配置,依然可以保持模塊導入的抽象化。
讓頁面靜止:inert
屬性
在前端開發中,有時我們需要將某些元素暫時“隱藏”起來,從用戶視角和交互上完全忽略。這時,新的 inert
屬性就派上了用場。通過簡單地設置元素的 inert
屬性,整個元素及其子元素會從交互中消失。它們無法被點擊、聚焦,也會從可訪問性樹中移除,甚至頁面的“查找”功能也無法選中其中的文本。
這項功能在構建復雜交互時顯得尤其有用。例如,在一個多步驟的表單中,可以將所有步驟預先放在 DOM 中,但將不當前步驟的部分設置為 inert
,確保用戶無法誤用到未來或已完成的步驟,這樣的做法會極大提升用戶體驗和流程的嚴謹性。
有人可能會想到用這功能來實現模態框(modal),而 HTML 中的 <dialog>
標簽為此提供了天然支持,使得構建和管理模態框變得更加簡單和靈活,只需適當地使用即可。
多頁面視圖過渡
在以往的前端開發中,頁面之間的跳轉常常是直接刷新導致的生硬切換。然而,現在通過加入簡單的 CSS 規則,我們可以實現流暢的多頁面視圖過渡:
@view-transition {
navigation: auto;
}
一旦啟用這一特性,常規點擊鏈接導致的新頁面跳轉(在同一域名內)將能具備視圖過渡效果。默認情況下,這將為頁面切換添加淡入淡出的效果,令用戶的瀏覽體驗更加順滑。同時,這也為開發者提供了豐富的動畫控制,能在頁面加載之間設計出更加吸引人的過渡效果。
雖然視圖過渡依賴于 CSS 的開啟,但其真正的魅力和實用性更多地體現在 HTML 的應用中。想象一下如下代碼:
<!-- 首頁 -->
<div class="card">
<h3 style="view-transition-name: post-title-087afd;">博客文章標題</h3>
<p>...</p>
<a href="/blog-post">閱讀完整文章《博客文章標題》</a>
</div>
<!-- 博客文章頁 -->
<article>
<h1 style="view-transition-name: post-title-087afd;">博客文章標題</h1>
<p>...</p>
</article>
在這個例子中,我們將“卡片”視作一種從數據中生成的組件,并且這種組件可能是頁面上的眾多之一。因此,使用唯一的 view-transition-name
是實現細膩過渡效果的關鍵,而最好的介入點無疑是在 HTML 之中。
響應式視頻
現代網頁設計中,響應式圖像已經是提升網站性能和用戶體驗的常用技術。通過 HTML 提供的 <picture>
元素,我們可以靈活地控制 <source>
,根據不同條件切換源圖像,實現了內容的最佳展示。這個強大的概念原本源自 <video>
標簽,但由于一些原因,它曾從大多數瀏覽器中消失。然而,如今得益于 Scott Jehl 和他的團隊的努力,這一功能榮耀歸來。
借助 media
屬性,我們能夠為視頻源添加條件控制。雖然在實踐中,更多的可能是用于寬度查詢,但它幾乎能處理任何媒介特性。以下是一個簡單的例子:
<video autoplay controls playsinline muted loop>
<source media="(orientation: landscape)" src="sunset-landscape-1080.mp4">
<source src="sunset-portrait-1080.mp4">
</video>
在這個例子中,我們根據設備的方向進行視頻選擇:在橫向(landscape)模式下加載一個視頻文件,而在其他情況加載另一個。這使得視頻內容可以根據用戶的設備特性進行動態調整,不僅保證了視覺效果的一致性,也顯著優化了網絡性能。
詳細了解請看這個例子:https://www.htmhell.dev/adventcalendar/2024/19/
利用 <details>
標簽創建交互式手風琴效果
在網頁設計中, <details>
和 <summary>
標簽已經被廣泛使用,以便創建簡潔的折疊內容。自 2016 年以來,瀏覽器對這對標簽的支持已經成熟,不過近來這些功能又有了新的增強和清理。
開發者現在可以通過使用 name
屬性將 <details>
元素組合在一起,從而實現“獨占”手風琴效果——即一次只能打開一個內容塊:
<details name="group"><summary>第一項</summary> ... </details>
<details name="group"><summary>第二項</summary> ... </details>
<details name="group"><summary>第三項</summary> ... </details>
<details name="group"><summary>第四項</summary> ... </details>
雖然有些人認為一次只能打開一個是反用戶體驗的,因為它會自動關閉用戶可能想保持打開的內容,但在特定的網頁設計中這一特性可能會很有效。然而,使用“手風琴”這個術語來描述這種模式還是頗為恰當的。同時,我們也必須注意到,使用這種模式在可訪問性上可能存在一些問題。例如,用于常見問題解答部分時,如果每個問題通常會作為類似 <h3>
這樣的標題,那么 <summary>
會將這種語義抹去,使其變成一個“按鈕”。這種做法在語義上不夠理想。
此外, <details>
元素可以在 Flexbox 布局中使用,表現得體。然而,僅最近這些表現有所改進。
在 CSS 方面,現在引入了一個新的選擇器 ::details-content
,幫助我們訪問和處理 <details>
中的 HTML 內容。這使得創建帶有動畫效果的折疊內容變得更加簡便,只需利用 HTML 和 CSS 即可實現開關動畫。
閱讀原文:原文鏈接
該文章在 2025/1/24 9:45:06 編輯過