CSS Houdini 可能是 CSS 中最令人兴奋的开发。Houdini 由许多单独的 API 组成,每个 API 都单独发布到浏览器,有些 API 已经发布了(浏览器支持情况)。Paint API 就是其中之一。我对它非常兴奋,最近开始思考如何在工作中使用它。
我能够做到这一点的一种方法是将其用作避免重复造轮子的方法。在本文中,我们将介绍这一点,同时将其与我们目前在 JavaScript 和 CSS 中使用的方法进行比较。(我不会深入探讨如何编写 CSS Houdini,因为已经有许多很棒的文章,例如 这篇、这篇 和 这篇。)
Houdini 为 CSS 带来了模块化和可配置性
CSS Houdini 的工作方式带来了两大优势:**模块化**和**可配置性**。这两种方式都是使我们开发人员生活更轻松的常用方法。我们在 JavaScript 世界中经常看到这些概念,但在 CSS 世界中却很少看到……直到现在。
以下表格列出了我们针对某些用例的工作流程,比较了传统 CSS 与使用 Houdini 的情况。我还添加了 JavaScript 以进行进一步比较。您可以看到 CSS Houdini 允许我们更有效地使用 CSS,类似于 JavaScript 世界如何发展成为组件。
传统 CSS | CSS Houdini | JavaScript | |
---|---|---|---|
当我们需要常用的代码片段时 | 从头编写或从某个地方复制粘贴。 | 导入一个工作线程。 | 导入一个 JS 库。 |
根据用例自定义代码片段 | 手动调整 CSS 中的值。 | 编辑工作线程公开的自定义属性。 | 编辑库提供的配置。 |
代码共享 | 共享原始样式的代码,并附带有关如何调整每个部分的注释。 | 共享工作线程(将来,到包管理服务)并记录自定义属性。 | 将库共享到包管理服务(如 npm)并记录如何使用和配置它。 |
模块化
使用 Houdini,您可以导入一个工作线程并使用一行代码开始使用它。
<script>
CSS.paintWorklet.addModule('my-useful-paint-worklet.js');
</script>
这意味着无需每次都实现常用的样式。您可以拥有自己的工作线程集合,这些工作线程可用于任何项目,甚至可以彼此共享。
如果您除了样式之外,还希望为 HTML 和 JavaScript 提供模块化,那么 Web Components 就是解决方案。
这与我们在 JavaScript 世界中已经拥有的非常相似。大多数人不会重新实现常用的函数,例如节流或深度复制对象。我们只需导入库,例如 Lodash。
如果 CSS Houdini 的普及率提高,我可以想象我们会拥有 CSS Houdini 包管理服务,任何人都可以导入有趣的水瀑布布局、背景图案、复杂动画等的工作线程。
可配置性
Houdini 与 CSS 变量配合得很好,这在很大程度上增强了自身的能力。使用 CSS 变量,用户可以配置 Houdini 工作线程。
.my-element {
background-image: paint(triangle);
--direction: top;
--size: 20px;
}
在代码片段中,--direction
和 --size
是 CSS 变量,它们在 triangle
工作线程中使用(由 triangle
工作线程的作者定义)。用户可以更改属性以更新显示方式,甚至可以动态地 在 JavaScript 中更新 CSS 变量。
如果我们再次将其与我们在 JavaScript 中已经拥有的内容进行比较,JavaScript 库通常具有可以传递的选项。例如,我们可以为速度、方向、大小等传递值到轮播库,以使其按照我们想要的方式执行。在 CSS 中的元素级别提供这些 API 非常有用。
Houdini 工作流使我的开发流程更高效
让我们看一个完整的示例,说明整个过程如何协同工作以简化开发。我们将使用**工具提示**设计模式作为示例。我发现自己经常在不同的网站中使用这种模式,但不知何故每次新项目都要重新实现。
让我们简要回顾一下我以前的经验
- 好的,我需要一个工具提示。
- 它是一个框,一侧有一个三角形。我将使用伪元素来绘制三角形。
- 我可以使用透明边框技巧来绘制三角形。
- 此时,我很有可能翻阅我以前的项目以复制代码。让我想想……这个需要向上指,哪边是透明的?
- 哦,设计需要工具提示的边框。我必须使用另一个伪元素并为指向的三角形伪造一个边框。
- 什么?他们决定更改三角形的方向?!好的,好的。我将调整两个三角形的所有值……
这并不难。整个过程可能只需要五分钟。但让我们看看使用 Houdini 如何做得更好。
我构建了一个简单的工具提示工作线程,它有很多选项可以更改其外观。您可以在 GitHub 上下载它。
这是我的新流程,感谢 Houdini
- 好的,我需要一个工具提示。
- 我将导入此工具提示工作线程并使用它。
- 现在我将使用自定义属性对其进行修改。
<script>CSS.paintWorklet.addModule('my-tooltip-worklet.js')</script>
<style>
.tooltip-1 {
background-image: paint(tooltip);
padding: calc(var(--triangle-size) * 1px + .5em) 1em 1em;
--round-radius: 0;
--background-color: #4d7990;
--triangle-size: 20;
--position: 20;
--direction: top;
--border-color: #333;
--border-width: 2;
color: #fff;
}
</style>
这是一个演示!继续使用变量!
CSS Houdini 为模块化、可配置的样式共享打开了一扇大门。我期待看到开发人员使用和共享 CSS Houdini 工作线程。我正在尝试添加更多关于 Houdini 用法的实用示例。如果您有任何想法或想为 此仓库 做出贡献,请告诉我。
很遗憾,这篇文章完全忽略了 Sass 和 SCSS。我还没有遇到过 SCSS 和 CSS 自定义属性的组合无法产生简洁明了的工作流程的情况。
Styled-Components 提供了相同的解决方案,并且它与前端框架集成。
文章中提到的每个优点都可以通过 styled-components 实现。
它是 CSS 的未来。
好文章!
与 JavaScript 框架绑定的东西怎么会是“CSS 的未来”?
bingo。
Lazar,阅读这篇文章时,我也有同样的想法。我不明白能够通过脚本修改模块变量的优势。
从工具提示示例来看,这会危险地模糊关注点分离
团队现在必须在多个地方查看哪些视觉样式被覆盖了——这完全不对
可以使用 OOCSS 和修饰符/变体类来处理
如果担心特异性或规则权重,请使用 Harry Roberts 推广的反向 ITCSS 三角形
如果您担心在 OOCSS 中提前编写变体,请采用 Atomic 实践
他说的没错——每个人都喜欢他们的预处理器
最终,方法论 + 最佳实践 > HP、微软和谷歌的一些家伙认为我们需要使用的工具。
太棒了
我担心“模块化”CSS 的“问题”已经无需客户端部分不支持的 JavaScript 就能解决。CSS Houdini 当然令人兴奋且充满希望,但“模块化”问题已经通过类和构建系统解决了。
为什么不使用 styled-components 呢?
因为它与 React 绑定。
关于工作线程的自定义,自定义变量是普通的 CSS 变量,对吧?
所以你使用全局变量配置你的工作线程,没有任何作用域或其他东西来防止你的工作线程自定义与 CSS 中其他地方使用的 CSS 变量发生冲突?
它比我们现在拥有的要好得多,但作为一个程序员,它看起来……有点笨拙?
整个模块化的事情是一个红鲱鱼,除非你不在乎你的网站看起来如何……你的客户肯定会在乎。
这种东西只对组件库有用,它们拼命地尝试覆盖,并且过度使用 !important。
在哪里考虑创建单层选择器规则……在哪里考虑跨项目维护大型设计系统……
我可能会不受欢迎,但它确实是发生在 CSS 上的最好的事情。你的样式越接近原生 CSS,就越好。
如果它必须从 .js 文件加载,它是否在页面绘制完成后加载?是否会先出现闪烁,然后 CSS Houdini 重新绘制?
我找到了关于 Houdini 如何工作的更详细的解释。除了在 CSS 中创建自定义三角形之外,还有更多有趣的东西!
https://tsh.io/blog/css-houdini-future-frontend-development/
没有提到这样一个事实,即你可能很长时间都无法使用它,因为你未来几年都需要使用回退实现。而这个回退实现将花费与你描述的“传统”方法一样多的时间,因此没有节省时间。而且在那个时候,如果回退在所有浏览器中都能工作,为什么要使用 Houdini 呢?
目前,我并没有在您描述的好处中看到 Houdini 的优势。我看到的优势是它允许实现目前使用 CSS 根本无法实现的绘制算法。这是一个您可以逐步增强的场景。例如,渲染一个圆角按钮,但在最新版本的浏览器中,渲染一些奇怪的有机形状按钮。
在未来几年内,我认为实现你现在可以用 CSS 做的事情,而改为在 Houdini 中做这些,是一个坏主意。这没有意义。