2020 年 v1 获得完全支持以来,Web Components 的世界发生了更多的变化。未来还有更多的计划。让我们看一些使用当前标准构建的值得关注的例子,以及调查一些将在 2023 年及以后推出的新的 Web Components 标准工作。
原文链接:https://eisenbergeffect.medium.com/2023-state-of-web-components-c8feb21d4f16
译文链接:https://blog.5bang.top/2023/04/21/2023_state_of_web_component
未经允许,禁止转载!
随着所有浏览器都支持 v1 Web Components,许多公司已经采用并基于这些新标准构建了重要的业务。以下是我认为值得关注的一些例子。
YouTube
YouTube 是最早采用 Web Components 技术的应用之一,多年来一直使用这种技术构建其界面。检查源代码,你会看到各种自定义元素,从 ytd-video-preview 到 iron-ally-announcer。
是的,Adobe 使用 Lit 将 Photoshop 带到了浏览器中。它现在还处于 beta 版本,如果你是 Adobe 的订阅用户,可以自行尝试。整个应用程序中有很多自定义元素,从构成应用程序根的 psw-app,到像 psw-layers-panel 这样的 shell 元素,再到像 sp-action-button 这样的 UI 组件。
几年前,微软使用基于 FAST 的 Web Components 重构了 MSN。这将性能提高了 30% 到 50%,比之前使用 React 构建的版本性能更好。
基于 OpenAI 的 New Bing 也是使用 FAST Web Components 构建的,如下面的屏幕截图所示,最近由其中一位开发人员分享。
甚至用于扩展 VS Code 新功能的 Webview UI 工具包,也是使用 FAST Web Components 构建的。
在过去三年中,微软大约有 1,500 个团队/项目采用了 FAST Web Components。
作为客户关系管理(CRM)、销售和营销自动化平台行业中最大的品牌之一,Salesforce 多年来一直在基于 Lightning Web Components 进行开发。
如今,Web Components 甚至在太空中也得到了应用。SpaceX 的机组人员显示屏正在运行 Chromium,广泛使用 Web Components。
Web 标准不断发展,其中包括 Web Components。自从 v1 版本发布到所有主流浏览器以来的三年中,Web Components 下的功能数量几乎翻了一倍。以下是各种已发布、正在进行和计划中的 Web Components 相关标准的图示。
让我们逐一查看图示中按照功能划分的六个高级类别中的每一项:组合和作用域、平台互操作性、渲染和性能、样式、包和分发、API 范式。
Web 组件的作用域/封装特性对于传统编程中的信息隐藏、维护、代码库可扩展性等方面同样非常重要。但是,当涉及到 Web Components 时,它们还为 HTML 和 CSS 运行时提供了额外的元数据,可以用来优化绘制和布局。
Shadow DOM
hadow DOM 是 HTML 中用于作用域、封装和组合 DOM 及相关样式的基本机制。它是一个多方面的特性,具有许多不断扩展的能力。
命名插槽分配(全面支持)—— 原始的 v1 Shadow DOM 规范提供了一种完全声明式的机制,用于在 Shadow DOM 中使用命名的 <slot>元素来定义元素组合的占位符。开发者只需在宿主元素的任何子元素上放置一个 slot 属性,浏览器就会自动『插入』该元素的呈现输出到插槽的位置。
开放和封闭模式(全面支持)—— v1 Shadow DOM 规范中的 attachShadow() API 的 mode 选项是其中一部分。它允许组件开发者选择其首选的封装模式。open 模式允许从宿主元素外部访问 shadowRoot,而 closed 模式则禁止访问。
事件重新定向(全面支持)—— 当在 Shadow DOM 内部的元素上触发事件时,这些事件会被『重新定向』,以便它们看起来来自宿主 Shadow DOM。这个 v1 Shadow DOM 规范的能力是正确封装内部结构的重要部分。
手动插槽分配(全面支持)—— slot 元素上的新的 assign API 扩展了 v1 的原始插槽分配功能,除了之前的声明性式插槽机制外,还提供了一种命令式 API。
焦点委托(全面支持)—— 这个在 v1 之后的特性使 Shadow DOM 可以告诉浏览器,当其宿主元素获得焦点时,它应该将焦点委托给 Shadow DOM 中的特定元素。默认情况下,第一个可聚焦的元素被选中,但可以使用 autofocus 属性覆盖该行为。
Cross-root ARIA(接近共识)—— 即将到来的特性,与社区和浏览器厂商接近达成共识,Cross-root ARIA 将极大简化在 Shadow DOM 外部与 Shadow DOM 内部的 ARIA 关键元素相关联的操作。例如,将 Shadow DOM 外部的 label 元素与 Shadow DOM 内部的 input 元素关联起来。这些类型的 ARIA 场景今天已经有解决方案,但并不是容易实现的。Cross-root ARIA 将大大改善这种情况。
在 Shadow CSS 中使用自定义属性(共识)—— 如今,一些浏览器可以使用 @property 语法来自定义 CSS 属性。但是,目前在 Shadow DOM 中尚不起作用。CSS 对象模型始终可以从自定义元素代码中来全局定义这些属性,但在 Shadow DOM 中以声明形式提供此功能是一个常识性的改进。这已达成共识,因此希望我们很快就能看到这个功能。随着浏览器更普遍地支持新的 CSS 语法。
作用域元素注册表(共识)
自定义元素的 v1 规范中,所有元素都通过 customElements 全局对象在全局自定义元素注册表中注册。这个新的补充功能使得能够实例化非全局注册表并在其中注册自定义元素。
const myRegistry = new CustomElementRegistry();myRegistry.define("my-element", MyElement);
这个注册表中的元素仅定义为该注册表所分配的 Shadow DOM。这极大地改进了浏览器中的作用域,使得可以按照需要为每个 shadow root 定义元素。当它被应用到浏览器中时,这将会是一个巨大的进步,为新的架构可能性打开了大门。目前,社区和厂商之间已经达成共识,Chromium 正在开发第一个实现。
Web Components 最重要的方面之一是它们如何在组件和平台之间实现互操作性。让我们看一些当前和未来的特性。
自定义元素
自治自定义元素(全面支持)—— Web Components v1 的这个核心功能通过向 customElements 全局对象注册一个类来定义继承自 HTMLElement 的自定义元素。基本的生命周期回调和观察属性也是规范的一部分。
自定义内置元素(已拒绝)—— 最初,有一个提案允许从内置元素(例如 HTMLParagraphElement)继承,但 WebKit 实现者发现了几个技术问题,因此已经拒绝了这个规范。它很可能在将来被删除,所以应该避免使用。请参见下面的『自定义属性』,了解可能更好的替代方案。
Element Internals
一个 v1 之后的新 API,ElementInternals,使得自定义元素能够更深入地与现有的 DOM 子系统进行平台级集成。
Shadow Root 访问(全面支持) —— 这个简单的功能添加使组件开发者可以检索一个 closed 模式元素的 Shadow Root 实例。如果没有这个功能,具有 closed 模式声明式 Shadow DOM 的元素将无法在运行时访问其根节点。
与表单关联的自定义元素(全面支持) —— 这个重要的新功能使得自定义元素能够完全参与表单,包括表单验证、提交和重置。
默认可访问性角色、状态和属性(大多数已支持) —— 这个新的 API 集合 使得可以通过直接在内部与平台进行通信来设置自定义元素的默认可访问性特性,而不是通过可能被用户无意中删除的宿主元素上的外部属性。目前,除 Firefox 外的所有主要浏览器都支持这个新的 API,对于 Firefox,则提供了一个 polyfill。由于 Firefox 已经实现了 ElementInternals 其他部分的 API,如果他们在不久的将来没有发布这个功能,我会感到惊讶。
组合选择(共识/无规范)
这个改进提出了一个新的 getComposedRange() API,用于 Selection 对象,它使得范围的起始和结束可以跨越多个 Shadow Root。它还将提升浏览器在处理这些情况时的一致性。对于 这个 API 草案,有普遍的共识,但在浏览器可以进行实现之前,仍需要一个完整的规范。在 Web Component 的正常开发过程中,你不太可能遇到这种情况。它主要涉及到富文本编辑器的实现。
自定义属性(已确定)
虽然这个功能不一定是 Web Components 的一部分,但它与 Web Components 旨在服务的场景有很高的重叠。这个草案提议启用可重用行为的创建,这些行为可以附加到任何 HTML 元素,遵循类似于 Web Components 的模式。例如,想象一下你想将 Material Design 水波纹效果应用到任何 HTML 元素上,那么这样做会不会很好呢?
<button material-ripple>Click Me</button>在我为 TPAC 2022 准备的草案提案中,我演示了这个功能的编程模型可能是什么样的: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 是一致的。这也将为被拒绝的可定制内置自定义元素提案中的 is 属性提供更好、更健壮的替代方案。渲染和性能对于 Web Components 来说非常关键。虽然基本功能已经就位,但这仍然是一个活跃的探索、讨论和未来创新的领域。
HTML Template 元素(全面支持)
HTMLTemplateElement及其定义惰性 HTML 内容的能力是 v1 Web 组件功能的关键部分。在引入该元素之前,没有办法声明不会被浏览器激活的 HTML,因此很难创建需要在需求时重复渲染相同 HTML 的组件。
声明式 Shadow DOM(大多数支持)
Shadow DOM 的 v1 规范仅允许通过 attachShadow() JavaScript API 创建 Shadow Root。这个 Shadow DOM 的新增增强功能允许在 HTML 中完全声明 Shadow DOM 内容,无需使用 JavaScript,为服务器框架提供了有趣的可能性。
<host-element><template shadowrootmode="open"><slot></slot></template><h2>Light content</h2>></host-element>
这个规范重用了 template 元素。不要被这个搞混了。它不是一个模板,它是由 HTML 解析器流入 Shadow Root 的活动 DOM。
当前除了 Firefox 之外,所有浏览器都支持声明式 Shadow DOM。 如果需要,该功能可以通过几行 JavaScript 代码进行 polyfill。
子节点更改回调函数(提议)
Web Components 在自定义元素的 v1 规范中有一个明确定义的生命周期,但这并不意味着我们不能在未来扩展这个生命周期。其中一个常见的对于开发者的挑战是使 Web Component 能够对子节点的添加或删除做出响应。虽然现在可以使用 slotchange事件 和 MutationObserver 实现这一点,但是如果有一个像 childrenChangedCallback() 这样的生命周期回调函数,可以提供更好的性能、简化和与 HTML 解析器本身的集成,那就更好了。目前有一个草案提议,并且实现者也表现出了兴趣。需要一份完整的提案来推动这个功能进入下一个阶段。
模板实例化
虽然 HTML 有模板,但它还没有一种机制来实例化与数据连接的模板,并在其相关数据更改时更新它们。这个『模板实例化』的领域有几个独立有价值的部分。
DOM 部件(提议) - 这个提案 将提供一种标准机制,在 DOM 树的特定位置插入或替换内容。你可以把它看作是一种低级别的启用器,帮助创建更高效的模板引擎和批量更新现有的 Web Component 库和 JavaScript 框架。它不提供响应性解决方案或模板语法,只提供定位和更新 DOM 部分的低级别标准基础设施。
模板语法(已确定) - 一旦定位和批量更新的低级别基础设施就位并被现有库成功使用,那么关于语法的大辩论就会开始。模板语法是一个非常有争议的问题,但我们已经认识到 HTML 应该有一个基本的语言来处理这个问题,即使它只是为其他库提供编译目标。
响应性(已确定) - DOM 部件提供批量更新 DOM 的标准机制。模板语法提供声明式机制来创建 DOM 部分。剩下的是确定何时应执行 DOM 部件更新的机制。这就是响应性的作用,以完成整个图景。这是另一个有争议的问题,但已经有一些先例,例如通过 Web Components 的 attributeChangedCallback()。这个主题需要更多的探索。
模板实例化工作类别被分解为上述三个子特性,旨在先解决某些较少有争议的问题,并为现有库和框架提供路径,以利用不那么主观的、改进性能的功能,避免在社区中引起过多争议。
虽然 Shadow DOM 提供了样式的封装,但有许多 CSS 特性直接与 Web Components 相关,并且在日常使用中非常重要。
使用
几项当前和未来的标准与 Web Components 如何使用样式来创建 Shadow DOM 的呈现方式有关。虽然一直以来都可以在 Shadow DOM 中创建样式元素,但新标准提供了更好的可读性和性能优势。
可构建样式表(全面支持) — 你知道在这个标准之前实际上无法创建 CSSStyleSheet 实例吗?这个标准修复了这个问题,现在您可以编写代码 new CSSStyleSheet()。这种能力使得在 Web Components 中更动态地创建和使用样式成为可能,包括在组件之间共享样式表。
采用样式表(全面支持) — 针对给定的 CSSStyleSheet 实例,如何将其与特定的 Shadow Root 或全局 document 关联起来?这个新标准 在 document 和所有 Shadow Root 实例中添加了一个 adoptedStyleSheets 数组。只需将样式表推入该数组中,就可以开始使用了。
CSS 模块脚本(Chromium) — 可构建样式表和采用样式表本身提供了创建、共享和关联文档表的原始机制,但仍需要在 JavaScript 中编写 CSS 代码。CSS 模块脚本标准 允许使用 JavaScript 模块导入.css 文件,从而平台会自动创建一个 CSSStyleSheet 实例,无需在 CSS 运行时和 JavaScript 运行时之间来回切换。
声明式 CSS 模块(已确定) — 随着声明式 Shadow DOM 和采用样式表的出现,已经创建了几个临时提议,以便声明 CSS 模块并将其与声明式 Shadow DOM 关联。这方面需要更多的探索,但这是 HTML 和 CSS 未来的一个令人兴奋的可能性。
呈现
主要来说,CSS 关注的是呈现方面的问题。有一些标准扩展了 Web Components 的样式设置的可能性。
不仅仅是 Web Components,对于创建组件系统来说,自定义 CSS 属性 是一个非常重要的规范,它能够创建本地 CSS 变量,并可以在 shadow roots 中使用。
CSS Shadow Parts(全面支持) — CSS 部分 允许在 Shadow DOM 中声明元素作为『部分』,可以使用外部选择器对其进行样式设置。这是通过 part 属性和 the exportparts 属性 实现的,用于嵌套场景。
CSS 自定义状态(Chromium) — 原生元素可以具有自定义状态,在 CSS 选择器中可用。例如,复选框的『已选中』和『未选中』状态。这个新功能 允许 Web Components 定义自己的状态。已经达成共识,Chromium 已经发布了第一个实现,可以通过 ElementInternals 访问。在等待其他浏览器跟进时,可以使用 polyfill 进行支持。
CSS 主题(提议) — 尽管可以通过仔细使用 CSS 自定义属性和 CSS Shadow Parts 来实现丰富的主题化,但可以通过明确地将主题的概念引入 CSS来简化和改进这一过程。
开放式 Shadow Root 样式(已确定) — 尽管可以使用可构建样式表和采用样式表使任何全局 CSS 在 Shadow Root 中共享,但对于普通 Web 开发人员来说,这可能不是一个直观的过程。有一些探索机制的方法,明确选择允许外部 CSS 进入某些 shadow roots。
到目前为止,我们主要谈论了与 Web Components 实现相关的标准。但同样重要的是考虑组件如何打包和加载。
自定义元素懒加载(提议)
现在,我们可以使用全局的 customElements 注册表定义组件,很快还可以使用自定义注册表。但是,在这两种情况下,在定义组件之前,组件的实现必须已经被加载。使用自定义元素懒加载,开发人员将能够告诉平台有关元素的信息,但是可以延迟加载它,直到元素首次出现在 document 中时才加载。它可能会像这样工作:
customElements.defineLazy("my-element",async () =\> (await import("my-element.js")).default);
这个规范似乎被大多数人认为是一种很好的东西,尤其是对于某些架构来说。然而,该提议的细节仍在争论中。
HTML 模块脚本(已确定)
HTML 模块脚本是 CSS 模块脚本的 HTML 等效物。通过 HTML 模块脚本提案,模板(和其他 HTML 片段)将通过 JS 模块系统直接可导入。目前只有一个草案提案,还需要进一步讨论许多细节,但这被认为是一个重要的长期增强功能,特别是考虑到未来可能存在只有单个 HTML 文件的 Web Components 的情况。
最后一个标准类别与我之前讨论的所有内容有些不同。这些标准涉及 Web Components 的基本编程范式。Web Components v1 主要是一种命令式的 JavaScript 编程模型。有一些值得注意的例外,比如声明式的 slot 分配。但基本上,它完全是命令式的。自 v1 以来,我们一直在努力引入越来越多的声明式特性。其中一个很好的例子是声明式 Shadow DOM。总的来说,最好为所有场景提供声明式和命令式的 API。但最终目标是拥有某种完全声明式定义的 Web Components,以便服务器可以向浏览器发送元素定义,在 noscript 上下文中可以完全工作。我们还有一段路要走,但当我们到达那里时,它将从根本上改变客户端和服务器开发。
标准的工作永远在进行中。事实上,从今天开始,W3C Web 组件社区组正在召开其 2023 年春季面对面活动。就像 TPAC 一样,这是一个机会,供库作者、组件创建者、浏览器厂商等聚集在一起,并花费专门的时间来解决仍需要共识或存在开放问题的规范的细节。我期待在后续的博客文章中向大家更新活动结果。
我希望本次的 Web Components 标准之旅对你来说是有意义的。你看到我们已经走了多远,未来还有什么等待我们,这很有趣。随着 v1 版本的发布,过去几年中已经发布的功能翻了一番,以及即将到来令人兴奋的新功能,现在是成为 Web 开发人员的好时机。
零开始,探索如何使用 TailwindCSS 自定义动画
Tailwind CSS是一种颠覆性的CSS框架,改变了开发者处理前端开发的方式。它的低级性和移动优先的方法使得它成为设计独特、响应式和可扩展的网页设计的热门选择。此外,它还具有强大的动画支持,使开发者能够构建引人入胜的用户体验,吸引访问者。
本文将详细介绍如何使用TailwindCSS进行动画设计。我们将逐步介绍框架提供的不同种类的动画,并提供步骤说明,帮助您将它们整合到应用程序中。本文将引导个人通过添加简单的悬停动画以及更复杂的动画来掌握必要的技能和专业知识,为您的网站创建引人入胜的动画效果。
1、首先,我们应该在React应用程序中安装和设置TailwindCSS,具体步骤如下:通过运行以下命令并选择React作为框架来创建一个React应用程序:
npm init vite2、接下来,使用以下命令安装TailwindCSS和其他依赖项,如postcss和autoprefixer:
npm install -D tailwindcss postcss autoprefixer3、运行命令 "npx tailwindcss init -p" 来创建配置文件,并打开 tailwind.config.js 文件,将其内容替换为提供的代码片段。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}最后,在 src/index.css 文件中粘贴以下代码片段:
@tailwind base;
@tailwind components;
@tailwind utilities;现在我们可以在React应用程序中使用TailwindCSS了。
Tailwind CSS默认提供了四个动画属性,用于为您的网页添加一些视觉效果。这些动画旨在简单地集成到您的项目中,以改善用户体验。
在这里,我们将详细介绍每个动画,提供完整的示例,演示如何将它们整合到我们的网站设计中。
想要在您的网站上添加加载或旋转动画吗?只需包含 "animate-spin" 属性,动画将自动应用。让我们来看一个例子。
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" 属性,用于淡入淡出元素。这个属性特别适用于创建骨架加载器和其他类似的视觉效果。
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。这个属性创建了一个雷达信号或水波纹效果,非常适合通知徽章和其他类似的设计元素。
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;运行后的效果如下:
这些是默认的动画,也可以应用于悬停或激活状态:
<button type="button" className="hover:animate-ping"> Processing… </button>这些动画可以应用于响应式断点。
<button className="md:animate-ping">Processing…</button>注:当屏幕宽度大于等于 md (medium)断点时,为按钮元素添加动画效果 animate-ping,以增强用户体验。同时,按钮上显示 "Processing..." 文字,表示正在处理中。
TailwindCSS通过传递单个属性,提供了一个简单的方法来使用内置动画。但是,开发者也可以根据自己的要求创建自定义动画。
例如,您可以通过修改 "tailwind.config.css" 文件来设计独特的动画。这使开发者能够生成与其项目需求完全适配的动画。
在 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: [],
}在这个例子中,它创建了一个名为 "button-rotate" 的自定义动画,包括一个无限循环、一个 "ease-in-out" 缓动函数和每个循环持续时间为两秒。
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,开发者可以在框架内使用独特的 CSS 属性,这得益于一个称为 "任意值" 的功能。
通过在 TailwindCSS 类中添加方括号中的值,此功能使设计方面的调整如位置和填充变得更加灵活。
例如,我们可以包括 padding-[5px]、bottom-[17px] 等属性。
简而言之,TailwindCSS 中的任意值特性提供了灵活性和定制选择,快速生成具有美观效果的网页设计。
同样的,也可以用来创建自定义动画。
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]",具有特定的设置。现在,让我们立即指定关键帧。
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: [],
}
这样做的结果将与我们在自定义动画部分指定的相同。
当您掌握了 TailwindCSS 的动画功能后,您将可以通过使用内置动画属性或创建自定义动画来轻松地为网页增添视觉效果,从而提升用户体验。
通过在 TailwindCSS 类中使用任意值,您还可以调整设计方面的其他细节。这个特性提供了灵活性和个性化的选择,以便快速生成美观的网页设计。
希望您通过本文学习到如何使用 TailwindCSS 创建自定义动画,并能将这些知识应用到您的网页设计中。
在文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。
原文:https://levelup.gitconnected.com/customizing-tailwind-css-animations-advancing-your-web-design-skills-dc9667494993
作者:Nitin Sharma
非直接翻译,有自行改编和添加部分,翻译水平有限,难免有疏漏,欢迎指正
辑导语:虽然国内软件的iPad用户占比不大,但依然存在着横屏适配的需求。本文作者讲述了自己做iPad横屏适配的背景,并对竞品的适配方式进行了分析研究,用自己的亲身经历提供了参考,推荐对ipad横屏适配感兴趣的童鞋阅读。
在我参与的一款资料查询 App 中,对 iPad 只支持竖屏以手机 UI 尺寸拉伸,每个季度都有用户反馈希望适配 iPad 横屏。经过询问用户发现,因为 iPad mini 尺寸刚好可以放在工作服口袋中,随时拿出来使用,而 iPad 屏幕远比手机大,浏览资料视野更大更舒服。
但另外一方面,后台数据显示当前 iPad 用户占比只有 1%,用户呼声够不上星星之火,不足以燎原。先别谈说服团队做 iPad 横屏适配,连说服自己都难。本来以为这事就像水中投石,水波消散就没有下文了。直到有一天,同样是资深用户的高管自己拿着 iPad 装上我们的 App 用了几天,终于忍不了,开始推动 iPad 横屏适配。
我们肯定不是第一个做 iPad 横屏适配的,但在网上搜了一圈,别说横屏适配,连 iPad 界面设计的文章都很少,下面 3 篇算不错的。这也是我决定写下本文的原因,为后来者提供经验,少踩坑。
没得经验参考就只能先从竞品分析开始了。经过对 iOS 系统应用、微信、QQ、微信阅读、得到、豆瓣、淘宝和有道词典的分析,我和同事总结成 5 种横屏适配模式。
典型 App:iOS 应用商店
特征:标题栏和 Tabbar 通栏拉伸,内容区根据宽度向右响应式布局。
适用场景:全部场景。
评价:灵活性和用户体验都很好,但设计和开发成本很大。
典型 App:iOS 设置、淘宝、微信、QQ
特征:左右分开显示,左边通常固定显示首页或者目录导航。右侧根据左侧选择显示对应的详情内容。
适用场景:频繁需要使用导航切换内容。
评价:用户体验适中,合理的利用横屏更大地展示更多的内容。设计成本小,需额外设计一个右侧默认为空的情况。开发成本要看是否改程序架构,相当于把手机两个手机界面合并成一个屏幕,可能有些程序架构很难这么修改。
典型 App:微信阅读
特征:标题栏和 Tabbar 通栏拉伸,内容直接按竖屏的宽度显示。
适用场景:全部场景。
评价:用户体验适中,设计与开发成本小,大多数产品采用此模式,但是没有更好的展现横屏宽屏的优势。
典型 App:豆瓣
特征:横屏为全屏通栏拉伸,所有元素与竖屏一致。
适用场景:全部场景。
评价:设计和开发成本最小,但是相当于没有适配。用户体验较差,横屏情况下内容集中,左侧右侧很空,或者被拉得很长,阅读体验较差。
当然也不是所有 App 都采用单一的模式。比如微信阅读,在其他页面是按竖屏宽度显示。但到了图书阅读界面,则是左右分栏充分利用 iPad 大屏幕展现内容。
以上竞品分析所有截图我们都保存在 Figma 中,有需要的读者可前往获取。
链接:https://www.figma.com/community/file/1071850659054902697/iPad-横屏适配竞品分析
非常遗憾的是虽然高管牵头做适配,但开发资源确实有限。不能为了设计师邀功拿业绩就从头把 iOS App 重构一遍,因此我们决定用最少的资源做最核心的优化。
适配计划分为 2 期。第 1 期将所有页面用按竖屏宽度显示进行横屏适配。第 2 期挑选核心页面用内容响应式或左右分栏进行优化。
在第 1 期我们就踩坑了,按照原来的工作流程,我们将所有的 iPad 横屏页面做好线框图、再输出所有视觉效果图。虽然都是线上页面不用重新设计,只需要拉伸画面或者调整间距,但所有线上页面也是一个不小的工作量。
就在进行过程中,iOS 工程师就皱着眉头来提议,由于代码架构和资源所限,设计师如果调整的视觉效果图未必能 100% 实现。不如反过来,让他先把所有页面强行横屏,再由设计师走查发现问题进行修改,这样节省时间效果也可控。
可见,不同的项目类型可以采取不同的工作流程。iPad 横屏适配项目流程和常规工作流程刚好相反,以往是先设计再开发,改成先开发再走查,节省设计师产出效果图时间,也保障最终实现效果。
在第 2 期挑选核心页面时,我也犯了错误。最开始我觉得核心是脸面,因此挑选 Tabbar 导航的首页、个人中心等用户一打开 App 就看得到的页面进行优化。但实际上用户真正的核心使用场景是在详情页查阅资料,这才是真正的核心页面。
在得到主管纠正后,我们转而开始为资料阅读页面提供左内容右目录的布局,便于用户方便地在长文中精确定位想读的内容。
2 期计划并非适配的终结,随着 App 功能的迭代,此后老界面修改和新界面设计需要考虑到 iPad 横屏的适配问题,就成为了日常工作的内容了。
按照以往的项目总结,最后应该汇报项目数据结果。但由于 iPad 用户本身可怜的占比,即使我们官方公众号推文宣布适配 iPad 横屏后,也没有 iPad 用户站出来点赞,而是又引发出使用华为、小米等安卓 Pad 的用户,要求也适配。
考虑到不同的安卓品牌适配方式不一样,而且安卓厂商自己又有平行世界等通用兼容方案,我们就没再继续参与了。
虽然没有外部用户反馈,但公司内部同事和开发团队使用后确实感觉很棒。所以我觉得这次适配项目真正值得思考的是:如果一个需求用户反馈很少,也没有数据支撑,但对体验影响很大,如何推动团队进行优化呢?
作者:龙爪槐守望者,微信公众号:龙爪槐守望者
本文由 @龙爪槐守望者 原创发布于人人都是产品经理。未经许可,禁止转载。
题图来自 Unsplash,基于 CC0 协议
*请认真填写需求信息,我们会在24小时内与您取得联系。