2020 年 v1 獲得完全支持以來,Web Components 的世界發(fā)生了更多的變化。未來還有更多的計劃。讓我們看一些使用當(dāng)前標(biāo)準(zhǔn)構(gòu)建的值得關(guān)注的例子,以及調(diào)查一些將在 2023 年及以后推出的新的 Web Components 標(biāo)準(zhǔn)工作。
原文鏈接:https://eisenbergeffect.medium.com/2023-state-of-web-components-c8feb21d4f16
譯文鏈接:https://blog.5bang.top/2023/04/21/2023_state_of_web_component
未經(jīng)允許,禁止轉(zhuǎn)載!
隨著所有瀏覽器都支持 v1 Web Components,許多公司已經(jīng)采用并基于這些新標(biāo)準(zhǔn)構(gòu)建了重要的業(yè)務(wù)。以下是我認(rèn)為值得關(guān)注的一些例子。
YouTube
YouTube 是最早采用 Web Components 技術(shù)的應(yīng)用之一,多年來一直使用這種技術(shù)構(gòu)建其界面。檢查源代碼,你會看到各種自定義元素,從 ytd-video-preview 到 iron-ally-announcer。
是的,Adobe 使用 Lit 將 Photoshop 帶到了瀏覽器中。它現(xiàn)在還處于 beta 版本,如果你是 Adobe 的訂閱用戶,可以自行嘗試。整個應(yīng)用程序中有很多自定義元素,從構(gòu)成應(yīng)用程序根的 psw-app,到像 psw-layers-panel 這樣的 shell 元素,再到像 sp-action-button 這樣的 UI 組件。
幾年前,微軟使用基于 FAST 的 Web Components 重構(gòu)了 MSN。這將性能提高了 30% 到 50%,比之前使用 React 構(gòu)建的版本性能更好。
基于 OpenAI 的 New Bing 也是使用 FAST Web Components 構(gòu)建的,如下面的屏幕截圖所示,最近由其中一位開發(fā)人員分享。
甚至用于擴(kuò)展 VS Code 新功能的 Webview UI 工具包,也是使用 FAST Web Components 構(gòu)建的。
在過去三年中,微軟大約有 1,500 個團(tuán)隊/項目采用了 FAST Web Components。
作為客戶關(guān)系管理(CRM)、銷售和營銷自動化平臺行業(yè)中最大的品牌之一,Salesforce 多年來一直在基于 Lightning Web Components 進(jìn)行開發(fā)。
如今,Web Components 甚至在太空中也得到了應(yīng)用。SpaceX 的機(jī)組人員顯示屏正在運行 Chromium,廣泛使用 Web Components。
Web 標(biāo)準(zhǔn)不斷發(fā)展,其中包括 Web Components。自從 v1 版本發(fā)布到所有主流瀏覽器以來的三年中,Web Components 下的功能數(shù)量幾乎翻了一倍。以下是各種已發(fā)布、正在進(jìn)行和計劃中的 Web Components 相關(guān)標(biāo)準(zhǔn)的圖示。
讓我們逐一查看圖示中按照功能劃分的六個高級類別中的每一項:組合和作用域、平臺互操作性、渲染和性能、樣式、包和分發(fā)、API 范式。
Web 組件的作用域/封裝特性對于傳統(tǒng)編程中的信息隱藏、維護(hù)、代碼庫可擴(kuò)展性等方面同樣非常重要。但是,當(dāng)涉及到 Web Components 時,它們還為 HTML 和 CSS 運行時提供了額外的元數(shù)據(jù),可以用來優(yōu)化繪制和布局。
Shadow DOM
hadow DOM 是 HTML 中用于作用域、封裝和組合 DOM 及相關(guān)樣式的基本機(jī)制。它是一個多方面的特性,具有許多不斷擴(kuò)展的能力。
命名插槽分配(全面支持)—— 原始的 v1 Shadow DOM 規(guī)范提供了一種完全聲明式的機(jī)制,用于在 Shadow DOM 中使用命名的 <slot>元素來定義元素組合的占位符。開發(fā)者只需在宿主元素的任何子元素上放置一個 slot 屬性,瀏覽器就會自動『插入』該元素的呈現(xiàn)輸出到插槽的位置。
開放和封閉模式(全面支持)—— v1 Shadow DOM 規(guī)范中的 attachShadow() API 的 mode 選項是其中一部分。它允許組件開發(fā)者選擇其首選的封裝模式。open 模式允許從宿主元素外部訪問 shadowRoot,而 closed 模式則禁止訪問。
事件重新定向(全面支持)—— 當(dāng)在 Shadow DOM 內(nèi)部的元素上觸發(fā)事件時,這些事件會被『重新定向』,以便它們看起來來自宿主 Shadow DOM。這個 v1 Shadow DOM 規(guī)范的能力是正確封裝內(nèi)部結(jié)構(gòu)的重要部分。
手動插槽分配(全面支持)—— slot 元素上的新的 assign API 擴(kuò)展了 v1 的原始插槽分配功能,除了之前的聲明性式插槽機(jī)制外,還提供了一種命令式 API。
焦點委托(全面支持)—— 這個在 v1 之后的特性使 Shadow DOM 可以告訴瀏覽器,當(dāng)其宿主元素獲得焦點時,它應(yīng)該將焦點委托給 Shadow DOM 中的特定元素。默認(rèn)情況下,第一個可聚焦的元素被選中,但可以使用 autofocus 屬性覆蓋該行為。
Cross-root ARIA(接近共識)—— 即將到來的特性,與社區(qū)和瀏覽器廠商接近達(dá)成共識,Cross-root ARIA 將極大簡化在 Shadow DOM 外部與 Shadow DOM 內(nèi)部的 ARIA 關(guān)鍵元素相關(guān)聯(lián)的操作。例如,將 Shadow DOM 外部的 label 元素與 Shadow DOM 內(nèi)部的 input 元素關(guān)聯(lián)起來。這些類型的 ARIA 場景今天已經(jīng)有解決方案,但并不是容易實現(xiàn)的。Cross-root ARIA 將大大改善這種情況。
在 Shadow CSS 中使用自定義屬性(共識)—— 如今,一些瀏覽器可以使用 @property 語法來自定義 CSS 屬性。但是,目前在 Shadow DOM 中尚不起作用。CSS 對象模型始終可以從自定義元素代碼中來全局定義這些屬性,但在 Shadow DOM 中以聲明形式提供此功能是一個常識性的改進(jìn)。這已達(dá)成共識,因此希望我們很快就能看到這個功能。隨著瀏覽器更普遍地支持新的 CSS 語法。
作用域元素注冊表(共識)
自定義元素的 v1 規(guī)范中,所有元素都通過 customElements 全局對象在全局自定義元素注冊表中注冊。這個新的補(bǔ)充功能使得能夠?qū)嵗侨肿员聿⒃谄渲凶宰远x元素。
const myRegistry = new CustomElementRegistry();
myRegistry.define("my-element", MyElement);
這個注冊表中的元素僅定義為該注冊表所分配的 Shadow DOM。這極大地改進(jìn)了瀏覽器中的作用域,使得可以按照需要為每個 shadow root 定義元素。當(dāng)它被應(yīng)用到瀏覽器中時,這將會是一個巨大的進(jìn)步,為新的架構(gòu)可能性打開了大門。目前,社區(qū)和廠商之間已經(jīng)達(dá)成共識,Chromium 正在開發(fā)第一個實現(xiàn)。
Web Components 最重要的方面之一是它們?nèi)绾卧诮M件和平臺之間實現(xiàn)互操作性。讓我們看一些當(dāng)前和未來的特性。
自定義元素
自治自定義元素(全面支持)—— Web Components v1 的這個核心功能通過向 customElements 全局對象注冊一個類來定義繼承自 HTMLElement 的自定義元素。基本的生命周期回調(diào)和觀察屬性也是規(guī)范的一部分。
自定義內(nèi)置元素(已拒絕)—— 最初,有一個提案允許從內(nèi)置元素(例如 HTMLParagraphElement)繼承,但 WebKit 實現(xiàn)者發(fā)現(xiàn)了幾個技術(shù)問題,因此已經(jīng)拒絕了這個規(guī)范。它很可能在將來被刪除,所以應(yīng)該避免使用。請參見下面的『自定義屬性』,了解可能更好的替代方案。
Element Internals
一個 v1 之后的新 API,ElementInternals,使得自定義元素能夠更深入地與現(xiàn)有的 DOM 子系統(tǒng)進(jìn)行平臺級集成。
Shadow Root 訪問(全面支持) —— 這個簡單的功能添加使組件開發(fā)者可以檢索一個 closed 模式元素的 Shadow Root 實例。如果沒有這個功能,具有 closed 模式聲明式 Shadow DOM 的元素將無法在運行時訪問其根節(jié)點。
與表單關(guān)聯(lián)的自定義元素(全面支持) —— 這個重要的新功能使得自定義元素能夠完全參與表單,包括表單驗證、提交和重置。
默認(rèn)可訪問性角色、狀態(tài)和屬性(大多數(shù)已支持) —— 這個新的 API 集合 使得可以通過直接在內(nèi)部與平臺進(jìn)行通信來設(shè)置自定義元素的默認(rèn)可訪問性特性,而不是通過可能被用戶無意中刪除的宿主元素上的外部屬性。目前,除 Firefox 外的所有主要瀏覽器都支持這個新的 API,對于 Firefox,則提供了一個 polyfill。由于 Firefox 已經(jīng)實現(xiàn)了 ElementInternals 其他部分的 API,如果他們在不久的將來沒有發(fā)布這個功能,我會感到驚訝。
組合選擇(共識/無規(guī)范)
這個改進(jìn)提出了一個新的 getComposedRange() API,用于 Selection 對象,它使得范圍的起始和結(jié)束可以跨越多個 Shadow Root。它還將提升瀏覽器在處理這些情況時的一致性。對于 這個 API 草案,有普遍的共識,但在瀏覽器可以進(jìn)行實現(xiàn)之前,仍需要一個完整的規(guī)范。在 Web Component 的正常開發(fā)過程中,你不太可能遇到這種情況。它主要涉及到富文本編輯器的實現(xiàn)。
自定義屬性(已確定)
雖然這個功能不一定是 Web Components 的一部分,但它與 Web Components 旨在服務(wù)的場景有很高的重疊。這個草案提議啟用可重用行為的創(chuàng)建,這些行為可以附加到任何 HTML 元素,遵循類似于 Web Components 的模式。例如,想象一下你想將 Material Design 水波紋效果應(yīng)用到任何 HTML 元素上,那么這樣做會不會很好呢?
<button material-ripple>Click Me</button>
在我為 TPAC 2022 準(zhǔn)備的草案提案中,我演示了這個功能的編程模型可能是什么樣的:
class MaterialRipple extends Attr {
// ownerElement inherited from Attr
// name inherited from Attr
// value inherited from Attr
// ...
connectedCallback () {
// called when the ownerElement is connected to the DOM
// or when the attribute is added to an already connected owner
}
disconnectedCallback () {
// called when the ownerElement is disconnected from the DOM
// or when the attribute is removed from a connected owner
}
attributeChangedCallback() {
// called when the value property of this attribute changes
}
}
customAttributes.define("material-ripple", MaterialRipple);
你會注意到,這個模式和生命周期與 Web Components 是一致的。這也將為被拒絕的可定制內(nèi)置自定義元素提案中的 is 屬性提供更好、更健壯的替代方案。
渲染和性能對于 Web Components 來說非常關(guān)鍵。雖然基本功能已經(jīng)就位,但這仍然是一個活躍的探索、討論和未來創(chuàng)新的領(lǐng)域。
HTML Template 元素(全面支持)
HTMLTemplateElement及其定義惰性 HTML 內(nèi)容的能力是 v1 Web 組件功能的關(guān)鍵部分。在引入該元素之前,沒有辦法聲明不會被瀏覽器激活的 HTML,因此很難創(chuàng)建需要在需求時重復(fù)渲染相同 HTML 的組件。
聲明式 Shadow DOM(大多數(shù)支持)
Shadow DOM 的 v1 規(guī)范僅允許通過 attachShadow() JavaScript API 創(chuàng)建 Shadow Root。這個 Shadow DOM 的新增增強(qiáng)功能允許在 HTML 中完全聲明 Shadow DOM 內(nèi)容,無需使用 JavaScript,為服務(wù)器框架提供了有趣的可能性。
<host-element>
<template shadowrootmode="open">
<slot></slot>
</template>
<h2>Light content</h2>>
</host-element>
這個規(guī)范重用了 template 元素。不要被這個搞混了。它不是一個模板,它是由 HTML 解析器流入 Shadow Root 的活動 DOM。
當(dāng)前除了 Firefox 之外,所有瀏覽器都支持聲明式 Shadow DOM。 如果需要,該功能可以通過幾行 JavaScript 代碼進(jìn)行 polyfill。
子節(jié)點更改回調(diào)函數(shù)(提議)
Web Components 在自定義元素的 v1 規(guī)范中有一個明確定義的生命周期,但這并不意味著我們不能在未來擴(kuò)展這個生命周期。其中一個常見的對于開發(fā)者的挑戰(zhàn)是使 Web Component 能夠?qū)ψ庸?jié)點的添加或刪除做出響應(yīng)。雖然現(xiàn)在可以使用 slotchange事件 和 MutationObserver 實現(xiàn)這一點,但是如果有一個像 childrenChangedCallback() 這樣的生命周期回調(diào)函數(shù),可以提供更好的性能、簡化和與 HTML 解析器本身的集成,那就更好了。目前有一個草案提議,并且實現(xiàn)者也表現(xiàn)出了興趣。需要一份完整的提案來推動這個功能進(jìn)入下一個階段。
模板實例化
雖然 HTML 有模板,但它還沒有一種機(jī)制來實例化與數(shù)據(jù)連接的模板,并在其相關(guān)數(shù)據(jù)更改時更新它們。這個『模板實例化』的領(lǐng)域有幾個獨立有價值的部分。
DOM 部件(提議) - 這個提案 將提供一種標(biāo)準(zhǔn)機(jī)制,在 DOM 樹的特定位置插入或替換內(nèi)容。你可以把它看作是一種低級別的啟用器,幫助創(chuàng)建更高效的模板引擎和批量更新現(xiàn)有的 Web Component 庫和 JavaScript 框架。它不提供響應(yīng)性解決方案或模板語法,只提供定位和更新 DOM 部分的低級別標(biāo)準(zhǔn)基礎(chǔ)設(shè)施。
模板語法(已確定) - 一旦定位和批量更新的低級別基礎(chǔ)設(shè)施就位并被現(xiàn)有庫成功使用,那么關(guān)于語法的大辯論就會開始。模板語法是一個非常有爭議的問題,但我們已經(jīng)認(rèn)識到 HTML 應(yīng)該有一個基本的語言來處理這個問題,即使它只是為其他庫提供編譯目標(biāo)。
響應(yīng)性(已確定) - DOM 部件提供批量更新 DOM 的標(biāo)準(zhǔn)機(jī)制。模板語法提供聲明式機(jī)制來創(chuàng)建 DOM 部分。剩下的是確定何時應(yīng)執(zhí)行 DOM 部件更新的機(jī)制。這就是響應(yīng)性的作用,以完成整個圖景。這是另一個有爭議的問題,但已經(jīng)有一些先例,例如通過 Web Components 的 attributeChangedCallback()。這個主題需要更多的探索。
模板實例化工作類別被分解為上述三個子特性,旨在先解決某些較少有爭議的問題,并為現(xiàn)有庫和框架提供路徑,以利用不那么主觀的、改進(jìn)性能的功能,避免在社區(qū)中引起過多爭議。
雖然 Shadow DOM 提供了樣式的封裝,但有許多 CSS 特性直接與 Web Components 相關(guān),并且在日常使用中非常重要。
使用
幾項當(dāng)前和未來的標(biāo)準(zhǔn)與 Web Components 如何使用樣式來創(chuàng)建 Shadow DOM 的呈現(xiàn)方式有關(guān)。雖然一直以來都可以在 Shadow DOM 中創(chuàng)建樣式元素,但新標(biāo)準(zhǔn)提供了更好的可讀性和性能優(yōu)勢。
可構(gòu)建樣式表(全面支持) — 你知道在這個標(biāo)準(zhǔn)之前實際上無法創(chuàng)建 CSSStyleSheet 實例嗎?這個標(biāo)準(zhǔn)修復(fù)了這個問題,現(xiàn)在您可以編寫代碼 new CSSStyleSheet()。這種能力使得在 Web Components 中更動態(tài)地創(chuàng)建和使用樣式成為可能,包括在組件之間共享樣式表。
采用樣式表(全面支持) — 針對給定的 CSSStyleSheet 實例,如何將其與特定的 Shadow Root 或全局 document 關(guān)聯(lián)起來?這個新標(biāo)準(zhǔn) 在 document 和所有 Shadow Root 實例中添加了一個 adoptedStyleSheets 數(shù)組。只需將樣式表推入該數(shù)組中,就可以開始使用了。
CSS 模塊腳本(Chromium) — 可構(gòu)建樣式表和采用樣式表本身提供了創(chuàng)建、共享和關(guān)聯(lián)文檔表的原始機(jī)制,但仍需要在 JavaScript 中編寫 CSS 代碼。CSS 模塊腳本標(biāo)準(zhǔn) 允許使用 JavaScript 模塊導(dǎo)入.css 文件,從而平臺會自動創(chuàng)建一個 CSSStyleSheet 實例,無需在 CSS 運行時和 JavaScript 運行時之間來回切換。
聲明式 CSS 模塊(已確定) — 隨著聲明式 Shadow DOM 和采用樣式表的出現(xiàn),已經(jīng)創(chuàng)建了幾個臨時提議,以便聲明 CSS 模塊并將其與聲明式 Shadow DOM 關(guān)聯(lián)。這方面需要更多的探索,但這是 HTML 和 CSS 未來的一個令人興奮的可能性。
呈現(xiàn)
主要來說,CSS 關(guān)注的是呈現(xiàn)方面的問題。有一些標(biāo)準(zhǔn)擴(kuò)展了 Web Components 的樣式設(shè)置的可能性。
不僅僅是 Web Components,對于創(chuàng)建組件系統(tǒng)來說,自定義 CSS 屬性 是一個非常重要的規(guī)范,它能夠創(chuàng)建本地 CSS 變量,并可以在 shadow roots 中使用。
CSS Shadow Parts(全面支持) — CSS 部分 允許在 Shadow DOM 中聲明元素作為『部分』,可以使用外部選擇器對其進(jìn)行樣式設(shè)置。這是通過 part 屬性和 the exportparts 屬性 實現(xiàn)的,用于嵌套場景。
CSS 自定義狀態(tài)(Chromium) — 原生元素可以具有自定義狀態(tài),在 CSS 選擇器中可用。例如,復(fù)選框的『已選中』和『未選中』狀態(tài)。這個新功能 允許 Web Components 定義自己的狀態(tài)。已經(jīng)達(dá)成共識,Chromium 已經(jīng)發(fā)布了第一個實現(xiàn),可以通過 ElementInternals 訪問。在等待其他瀏覽器跟進(jìn)時,可以使用 polyfill 進(jìn)行支持。
CSS 主題(提議) — 盡管可以通過仔細(xì)使用 CSS 自定義屬性和 CSS Shadow Parts 來實現(xiàn)豐富的主題化,但可以通過明確地將主題的概念引入 CSS來簡化和改進(jìn)這一過程。
開放式 Shadow Root 樣式(已確定) — 盡管可以使用可構(gòu)建樣式表和采用樣式表使任何全局 CSS 在 Shadow Root 中共享,但對于普通 Web 開發(fā)人員來說,這可能不是一個直觀的過程。有一些探索機(jī)制的方法,明確選擇允許外部 CSS 進(jìn)入某些 shadow roots。
到目前為止,我們主要談?wù)摿伺c Web Components 實現(xiàn)相關(guān)的標(biāo)準(zhǔn)。但同樣重要的是考慮組件如何打包和加載。
自定義元素懶加載(提議)
現(xiàn)在,我們可以使用全局的 customElements 注冊表定義組件,很快還可以使用自定義注冊表。但是,在這兩種情況下,在定義組件之前,組件的實現(xiàn)必須已經(jīng)被加載。使用自定義元素懶加載,開發(fā)人員將能夠告訴平臺有關(guān)元素的信息,但是可以延遲加載它,直到元素首次出現(xiàn)在 document 中時才加載。它可能會像這樣工作:
customElements.defineLazy(
"my-element",
async () =\> (await import("my-element.js")).default
);
這個規(guī)范似乎被大多數(shù)人認(rèn)為是一種很好的東西,尤其是對于某些架構(gòu)來說。然而,該提議的細(xì)節(jié)仍在爭論中。
HTML 模塊腳本(已確定)
HTML 模塊腳本是 CSS 模塊腳本的 HTML 等效物。通過 HTML 模塊腳本提案,模板(和其他 HTML 片段)將通過 JS 模塊系統(tǒng)直接可導(dǎo)入。目前只有一個草案提案,還需要進(jìn)一步討論許多細(xì)節(jié),但這被認(rèn)為是一個重要的長期增強(qiáng)功能,特別是考慮到未來可能存在只有單個 HTML 文件的 Web Components 的情況。
最后一個標(biāo)準(zhǔn)類別與我之前討論的所有內(nèi)容有些不同。這些標(biāo)準(zhǔn)涉及 Web Components 的基本編程范式。Web Components v1 主要是一種命令式的 JavaScript 編程模型。有一些值得注意的例外,比如聲明式的 slot 分配。但基本上,它完全是命令式的。自 v1 以來,我們一直在努力引入越來越多的聲明式特性。其中一個很好的例子是聲明式 Shadow DOM。總的來說,最好為所有場景提供聲明式和命令式的 API。但最終目標(biāo)是擁有某種完全聲明式定義的 Web Components,以便服務(wù)器可以向瀏覽器發(fā)送元素定義,在 noscript 上下文中可以完全工作。我們還有一段路要走,但當(dāng)我們到達(dá)那里時,它將從根本上改變客戶端和服務(wù)器開發(fā)。
標(biāo)準(zhǔn)的工作永遠(yuǎn)在進(jìn)行中。事實上,從今天開始,W3C Web 組件社區(qū)組正在召開其 2023 年春季面對面活動。就像 TPAC 一樣,這是一個機(jī)會,供庫作者、組件創(chuàng)建者、瀏覽器廠商等聚集在一起,并花費專門的時間來解決仍需要共識或存在開放問題的規(guī)范的細(xì)節(jié)。我期待在后續(xù)的博客文章中向大家更新活動結(jié)果。
我希望本次的 Web Components 標(biāo)準(zhǔn)之旅對你來說是有意義的。你看到我們已經(jīng)走了多遠(yuǎn),未來還有什么等待我們,這很有趣。隨著 v1 版本的發(fā)布,過去幾年中已經(jīng)發(fā)布的功能翻了一番,以及即將到來令人興奮的新功能,現(xiàn)在是成為 Web 開發(fā)人員的好時機(jī)。
零開始,探索如何使用 TailwindCSS 自定義動畫
Tailwind CSS是一種顛覆性的CSS框架,改變了開發(fā)者處理前端開發(fā)的方式。它的低級性和移動優(yōu)先的方法使得它成為設(shè)計獨特、響應(yīng)式和可擴(kuò)展的網(wǎng)頁設(shè)計的熱門選擇。此外,它還具有強(qiáng)大的動畫支持,使開發(fā)者能夠構(gòu)建引人入勝的用戶體驗,吸引訪問者。
本文將詳細(xì)介紹如何使用TailwindCSS進(jìn)行動畫設(shè)計。我們將逐步介紹框架提供的不同種類的動畫,并提供步驟說明,幫助您將它們整合到應(yīng)用程序中。本文將引導(dǎo)個人通過添加簡單的懸停動畫以及更復(fù)雜的動畫來掌握必要的技能和專業(yè)知識,為您的網(wǎng)站創(chuàng)建引人入勝的動畫效果。
1、首先,我們應(yīng)該在React應(yīng)用程序中安裝和設(shè)置TailwindCSS,具體步驟如下:通過運行以下命令并選擇React作為框架來創(chuàng)建一個React應(yīng)用程序:
npm init vite
2、接下來,使用以下命令安裝TailwindCSS和其他依賴項,如postcss和autoprefixer:
npm install -D tailwindcss postcss autoprefixer
3、運行命令 "npx tailwindcss init -p" 來創(chuàng)建配置文件,并打開 tailwind.config.js 文件,將其內(nèi)容替換為提供的代碼片段。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
最后,在 src/index.css 文件中粘貼以下代碼片段:
@tailwind base;
@tailwind components;
@tailwind utilities;
現(xiàn)在我們可以在React應(yīng)用程序中使用TailwindCSS了。
Tailwind CSS默認(rèn)提供了四個動畫屬性,用于為您的網(wǎng)頁添加一些視覺效果。這些動畫旨在簡單地集成到您的項目中,以改善用戶體驗。
在這里,我們將詳細(xì)介紹每個動畫,提供完整的示例,演示如何將它們整合到我們的網(wǎng)站設(shè)計中。
想要在您的網(wǎng)站上添加加載或旋轉(zhuǎn)動畫嗎?只需包含 "animate-spin" 屬性,動畫將自動應(yīng)用。讓我們來看一個例子。
import React from 'react';
function App() {
return (
<div className='w-screen h-screen flex justify-center items-center'>
<button
type="button"
className="flex bg-red-500 text-white px-4 py-2 rounded-md"
>
<svg className="h-5 w-5 mr-3 animate-spin" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
<path fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647zM12 20.735a8 8 0 008-8h4a12 12 0 01-12 12v-4.265zM20 12a8 8 0 01-8 8v4.265a12 12 0 0012-12h-4zm-8-6.735a8 8 0 018-8v-4.265a12 12 0 00-12 12h4z" />
</svg>
Processing...
</button>
</div >
);
}
export default App;
運行后的效果如下:
除了 "animate-spin" 屬性外,TailwindCSS 還提供了 "animate-pulse" 屬性,用于淡入淡出元素。這個屬性特別適用于創(chuàng)建骨架加載器和其他類似的視覺效果。
import React from 'react';
function App() {
return (
<div className='w-screen h-screen flex justify-center items-center'>
<button
type="button"
className="flex bg-red-500 text-white px-4 py-2 rounded-md animate-pulse"
>
<svg className="h-5 w-5 mr-3 animate-spin" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
<path fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647zM12 20.735a8 8 0 008-8h4a12 12 0 01-12 12v-4.265zM20 12a8 8 0 01-8 8v4.265a12 12 0 0012-12h-4zm-8-6.735a8 8 0 018-8v-4.265a12 12 0 00-12 12h4z" />
</svg>
Processing...
</button>
</div >
);
}
export default App;
運行后的效果如下:
要使元素上下彈跳,只需使用 animate-bounce。如果您想引起注意,這是很有用的。
import React from 'react';
function App() {
return (
<div className='w-screen h-screen flex justify-center items-center'>
<button
type="button"
className="flex bg-red-500 text-white px-4 py-2 rounded-md animate-bounce">
Processing...
</button>
</div >
);
}
export default App;
運行后的效果如下:
最后一個TailwindCSS動畫屬性是 animate-ping。這個屬性創(chuàng)建了一個雷達(dá)信號或水波紋效果,非常適合通知徽章和其他類似的設(shè)計元素。
import React from 'react';
function App() {
return (
<div className='w-screen h-screen flex justify-center items-center'>
<button
type="button"
className="flex bg-red-500 text-white px-4 py-2 rounded-md animate-ping"
>
Processing...
</button>
</div >
);
}
export default App;
運行后的效果如下:
這些是默認(rèn)的動畫,也可以應(yīng)用于懸停或激活狀態(tài):
<button type="button" className="hover:animate-ping"> Processing… </button>
這些動畫可以應(yīng)用于響應(yīng)式斷點。
<button className="md:animate-ping">Processing…</button>
注:當(dāng)屏幕寬度大于等于 md (medium)斷點時,為按鈕元素添加動畫效果 animate-ping,以增強(qiáng)用戶體驗。同時,按鈕上顯示 "Processing..." 文字,表示正在處理中。
TailwindCSS通過傳遞單個屬性,提供了一個簡單的方法來使用內(nèi)置動畫。但是,開發(fā)者也可以根據(jù)自己的要求創(chuàng)建自定義動畫。
例如,您可以通過修改 "tailwind.config.css" 文件來設(shè)計獨特的動畫。這使開發(fā)者能夠生成與其項目需求完全適配的動畫。
在 tailwind.config.js 文件中:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
animation: {
'button-rotate': 'button-rotate 2s ease-in-out infinite',
},
keyframes: {
'button-rotate': {
'0%': { transform: 'scale(1) rotate(0deg)' },
'50%': { transform: 'scale(1.5) rotate(180deg)' },
'100%': { transform: 'scale(1) rotate(360deg)' },
},
},
},
},
plugins: [],
}
在這個例子中,它創(chuàng)建了一個名為 "button-rotate" 的自定義動畫,包括一個無限循環(huán)、一個 "ease-in-out" 緩動函數(shù)和每個循環(huán)持續(xù)時間為兩秒。
App.js
import './App.css';
function App() {
return (
<div class="flex justify-center items-center h-screen w-screen">
<button class="animate-button-rotate bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full">
Click Me
</button>
</div>
)
}
export default App;
運行后的效果如下:
使用 TailwindCSS,開發(fā)者可以在框架內(nèi)使用獨特的 CSS 屬性,這得益于一個稱為 "任意值" 的功能。
通過在 TailwindCSS 類中添加方括號中的值,此功能使設(shè)計方面的調(diào)整如位置和填充變得更加靈活。
例如,我們可以包括 padding-[5px]、bottom-[17px] 等屬性。
簡而言之,TailwindCSS 中的任意值特性提供了靈活性和定制選擇,快速生成具有美觀效果的網(wǎng)頁設(shè)計。
同樣的,也可以用來創(chuàng)建自定義動畫。
import React from ‘react’;
function App() {
return (
<div class="flex justify-center items-center h-screen w-screen">
<button class="animate-[wiggle_1s_ease-in-out_infinite] bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full">
Click Me
</button>
</div>
);
}
export default App;
這里我們使用了 "animate-[wiggle_1s_ease-in-out_infinite]",具有特定的設(shè)置。現(xiàn)在,讓我們立即指定關(guān)鍵幀。
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
keyframes: {
'wiggle': {
'0%': { transform: 'scale(1) rotate(0deg)' },
'50%': { transform: 'scale(1.5) rotate(180deg)' },
'100%': { transform: 'scale(1) rotate(360deg)' },
},
},
},
},
plugins: [],
}
這樣做的結(jié)果將與我們在自定義動畫部分指定的相同。
當(dāng)您掌握了 TailwindCSS 的動畫功能后,您將可以通過使用內(nèi)置動畫屬性或創(chuàng)建自定義動畫來輕松地為網(wǎng)頁增添視覺效果,從而提升用戶體驗。
通過在 TailwindCSS 類中使用任意值,您還可以調(diào)整設(shè)計方面的其他細(xì)節(jié)。這個特性提供了靈活性和個性化的選擇,以便快速生成美觀的網(wǎng)頁設(shè)計。
希望您通過本文學(xué)習(xí)到如何使用 TailwindCSS 創(chuàng)建自定義動畫,并能將這些知識應(yīng)用到您的網(wǎng)頁設(shè)計中。
在文章結(jié)尾,我想提醒您,文章的創(chuàng)作不易,如果您喜歡我的分享,請別忘了點贊和轉(zhuǎn)發(fā),讓更多有需要的人看到。同時,如果您想獲取更多前端技術(shù)的知識,歡迎關(guān)注我,您的支持將是我分享最大的動力。我會持續(xù)輸出更多內(nèi)容,敬請期待。
原文:https://levelup.gitconnected.com/customizing-tailwind-css-animations-advancing-your-web-design-skills-dc9667494993
作者:Nitin Sharma
非直接翻譯,有自行改編和添加部分,翻譯水平有限,難免有疏漏,歡迎指正
輯導(dǎo)語:雖然國內(nèi)軟件的iPad用戶占比不大,但依然存在著橫屏適配的需求。本文作者講述了自己做iPad橫屏適配的背景,并對競品的適配方式進(jìn)行了分析研究,用自己的親身經(jīng)歷提供了參考,推薦對ipad橫屏適配感興趣的童鞋閱讀。
在我參與的一款資料查詢 App 中,對 iPad 只支持豎屏以手機(jī) UI 尺寸拉伸,每個季度都有用戶反饋希望適配 iPad 橫屏。經(jīng)過詢問用戶發(fā)現(xiàn),因為 iPad mini 尺寸剛好可以放在工作服口袋中,隨時拿出來使用,而 iPad 屏幕遠(yuǎn)比手機(jī)大,瀏覽資料視野更大更舒服。
但另外一方面,后臺數(shù)據(jù)顯示當(dāng)前 iPad 用戶占比只有 1%,用戶呼聲夠不上星星之火,不足以燎原。先別談?wù)f服團(tuán)隊做 iPad 橫屏適配,連說服自己都難。本來以為這事就像水中投石,水波消散就沒有下文了。直到有一天,同樣是資深用戶的高管自己拿著 iPad 裝上我們的 App 用了幾天,終于忍不了,開始推動 iPad 橫屏適配。
我們肯定不是第一個做 iPad 橫屏適配的,但在網(wǎng)上搜了一圈,別說橫屏適配,連 iPad 界面設(shè)計的文章都很少,下面 3 篇算不錯的。這也是我決定寫下本文的原因,為后來者提供經(jīng)驗,少踩坑。
沒得經(jīng)驗參考就只能先從競品分析開始了。經(jīng)過對 iOS 系統(tǒng)應(yīng)用、微信、QQ、微信閱讀、得到、豆瓣、淘寶和有道詞典的分析,我和同事總結(jié)成 5 種橫屏適配模式。
典型 App:iOS 應(yīng)用商店
特征:標(biāo)題欄和 Tabbar 通欄拉伸,內(nèi)容區(qū)根據(jù)寬度向右響應(yīng)式布局。
適用場景:全部場景。
評價:靈活性和用戶體驗都很好,但設(shè)計和開發(fā)成本很大。
典型 App:iOS 設(shè)置、淘寶、微信、QQ
特征:左右分開顯示,左邊通常固定顯示首頁或者目錄導(dǎo)航。右側(cè)根據(jù)左側(cè)選擇顯示對應(yīng)的詳情內(nèi)容。
適用場景:頻繁需要使用導(dǎo)航切換內(nèi)容。
評價:用戶體驗適中,合理的利用橫屏更大地展示更多的內(nèi)容。設(shè)計成本小,需額外設(shè)計一個右側(cè)默認(rèn)為空的情況。開發(fā)成本要看是否改程序架構(gòu),相當(dāng)于把手機(jī)兩個手機(jī)界面合并成一個屏幕,可能有些程序架構(gòu)很難這么修改。
典型 App:微信閱讀
特征:標(biāo)題欄和 Tabbar 通欄拉伸,內(nèi)容直接按豎屏的寬度顯示。
適用場景:全部場景。
評價:用戶體驗適中,設(shè)計與開發(fā)成本小,大多數(shù)產(chǎn)品采用此模式,但是沒有更好的展現(xiàn)橫屏寬屏的優(yōu)勢。
典型 App:豆瓣
特征:橫屏為全屏通欄拉伸,所有元素與豎屏一致。
適用場景:全部場景。
評價:設(shè)計和開發(fā)成本最小,但是相當(dāng)于沒有適配。用戶體驗較差,橫屏情況下內(nèi)容集中,左側(cè)右側(cè)很空,或者被拉得很長,閱讀體驗較差。
當(dāng)然也不是所有 App 都采用單一的模式。比如微信閱讀,在其他頁面是按豎屏寬度顯示。但到了圖書閱讀界面,則是左右分欄充分利用 iPad 大屏幕展現(xiàn)內(nèi)容。
以上競品分析所有截圖我們都保存在 Figma 中,有需要的讀者可前往獲取。
鏈接:https://www.figma.com/community/file/1071850659054902697/iPad-橫屏適配競品分析
非常遺憾的是雖然高管牽頭做適配,但開發(fā)資源確實有限。不能為了設(shè)計師邀功拿業(yè)績就從頭把 iOS App 重構(gòu)一遍,因此我們決定用最少的資源做最核心的優(yōu)化。
適配計劃分為 2 期。第 1 期將所有頁面用按豎屏寬度顯示進(jìn)行橫屏適配。第 2 期挑選核心頁面用內(nèi)容響應(yīng)式或左右分欄進(jìn)行優(yōu)化。
在第 1 期我們就踩坑了,按照原來的工作流程,我們將所有的 iPad 橫屏頁面做好線框圖、再輸出所有視覺效果圖。雖然都是線上頁面不用重新設(shè)計,只需要拉伸畫面或者調(diào)整間距,但所有線上頁面也是一個不小的工作量。
就在進(jìn)行過程中,iOS 工程師就皺著眉頭來提議,由于代碼架構(gòu)和資源所限,設(shè)計師如果調(diào)整的視覺效果圖未必能 100% 實現(xiàn)。不如反過來,讓他先把所有頁面強(qiáng)行橫屏,再由設(shè)計師走查發(fā)現(xiàn)問題進(jìn)行修改,這樣節(jié)省時間效果也可控。
可見,不同的項目類型可以采取不同的工作流程。iPad 橫屏適配項目流程和常規(guī)工作流程剛好相反,以往是先設(shè)計再開發(fā),改成先開發(fā)再走查,節(jié)省設(shè)計師產(chǎn)出效果圖時間,也保障最終實現(xiàn)效果。
在第 2 期挑選核心頁面時,我也犯了錯誤。最開始我覺得核心是臉面,因此挑選 Tabbar 導(dǎo)航的首頁、個人中心等用戶一打開 App 就看得到的頁面進(jìn)行優(yōu)化。但實際上用戶真正的核心使用場景是在詳情頁查閱資料,這才是真正的核心頁面。
在得到主管糾正后,我們轉(zhuǎn)而開始為資料閱讀頁面提供左內(nèi)容右目錄的布局,便于用戶方便地在長文中精確定位想讀的內(nèi)容。
2 期計劃并非適配的終結(jié),隨著 App 功能的迭代,此后老界面修改和新界面設(shè)計需要考慮到 iPad 橫屏的適配問題,就成為了日常工作的內(nèi)容了。
按照以往的項目總結(jié),最后應(yīng)該匯報項目數(shù)據(jù)結(jié)果。但由于 iPad 用戶本身可憐的占比,即使我們官方公眾號推文宣布適配 iPad 橫屏后,也沒有 iPad 用戶站出來點贊,而是又引發(fā)出使用華為、小米等安卓 Pad 的用戶,要求也適配。
考慮到不同的安卓品牌適配方式不一樣,而且安卓廠商自己又有平行世界等通用兼容方案,我們就沒再繼續(xù)參與了。
雖然沒有外部用戶反饋,但公司內(nèi)部同事和開發(fā)團(tuán)隊使用后確實感覺很棒。所以我覺得這次適配項目真正值得思考的是:如果一個需求用戶反饋很少,也沒有數(shù)據(jù)支撐,但對體驗影響很大,如何推動團(tuán)隊進(jìn)行優(yōu)化呢?
作者:龍爪槐守望者,微信公眾號:龍爪槐守望者
本文由 @龍爪槐守望者 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)許可,禁止轉(zhuǎn)載。
題圖來自 Unsplash,基于 CC0 協(xié)議
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。