响应式 CSS 属性
一个轻量级的库,可显著提升您的样式工作流程。借助响应式 CSS 属性 (re.css),您可以设置自定义 CSS 属性,并通过 JavaScript 实时响应属性变化。
目录
re.css 的优势
你可以把现代 JavaScript 看作有两个主要职责:更新业务逻辑和更新样式。后者的问题在于它增加了额外的开销和需要克服的新问题。re.css 规定 CSS 负责更新样式,而 JavaScript 应该……
想象一下这样的场景:我们正在你家乡参加一个科技大会,一个陌生的开发者走到你面前(那就是我),我对你说。
嘿,你的CSS是响应式的吗
?
🤨 你可能会想:
我应该回答这个问题吗?我沉默了很久,这好尴尬。
什么是响应式?
为什么要让 CSS 具有响应式?
最后……
嘿,别曲解我的意思。
这是一个很大的话题,但简单来说……一些数据会发生变化,JavaScript 会对这些变化做出响应,数据就像一根棍子一样被绑定到一个函数上,而棍子的另一端则被大量的胶水粘在了一起。可惜的是,我们今天并不打算讨论如何在荒岛上生存。
我明白你的意思,你可能觉得这只是个噱头,或者只是增加了复杂性?
我思考这个问题已经有一段时间了,我的结论是,传统的样式设置方式——即单独设置各个元素的样式,并期望整体效果保持一致——本身就很复杂。在用户交互时更新样式,同时还要处理业务逻辑的副作用,这是两个独立的问题,因此比我即将介绍的这种单一的样式逻辑处理方式要复杂得多。
如果我说:停止对 DOM 元素进行样式设置!是不是有点过头了?那你打算怎么设计漂亮的 UI 呢?
是的,这听起来有点傻,但实际上,真的是这样吗?CSS 自定义属性已经存在一段时间了,它们允许你为某种指针(而不是元素)设置样式。我觉得变量是任何语言中实现可重复结果的最佳方式,这正是保持一致性设计所需要的,对吧?需要说明的是,我仍然建议像往常一样使用样式类等等,但在运行时需要时可以使用更多变量,稍后我会详细说明。
不仅如此,自定义属性还可以有多种有用的功能。
提示:
如果使用 Sass 或任何预处理器,CSS 属性在运行时非常有用,不容忽视。事实上,你可以使用 Sass 变量构建自定义属性,我之前已经介绍过,效果非常惊艳。
好了,回到故事中;你现在已经回家了,正在琢磨我到底在说什么,re.css,那是什么?
我希望有一天当你搜索 re.css 时,会出现以下内容。
re.css 是一个样式指南(待办事项)和配套库,它从 css-in-js 分支而来,其目标是提供增强的性能、分离职责和改善用户体验。
如果你曾经用 JavaScript 设置过样式,无论是通过原生 JavaScript、React、Vue 还是 Angular,你都会遇到类似这样的情况。
呼,这其实是对加载一个典型的没有 SSR 的 SPA 的非常简化的描述,即使这样描述也相当复杂。
这几乎就像重复做同一件事一样,你可能会看到这样的画面:一闪而过的糟糕白色无样式内容,没人想看,你的用户想看点什么,任何东西都行,就是不想看到这个。这就像酒店员工朝你吐口水一样,一点也不友好😱。
当然,还有服务器端渲染(SSR)。服务器端渲染通常很有帮助,因为它可以解决渲染初期 HTML 和 CSS 尚未加载的问题,从而简化渲染流程。但使用 SSR 也有代价,你需要使用另一个针对你所选架构的框架来启用它。
如果我们换个方式呢?先在样式表中设置一个 CSS 变量,然后为组件渲染的占位元素设置样式。等 JavaScript 加载完毕后,再将该变量或一组变量的控制权交给 JavaScript。因为我之前忘了提一点:CSS 自定义属性是可以用 JavaScript 交互的!这样,在实际内容加载之前,你就能看到一些与内容大致相似的元素。再也不会出现未设置样式的内容闪烁了。
但情况会更好,如果你的所有 CSS 变量和样式大部分都位于样式表中,你只需要在 JavaScript 端设置属性(我提到过,当脚本使用时,它们就像指针一样),然后让浏览器处理其余部分,JavaScript 不需要进行任何进一步的计算。
但我听到你们反驳说:“我使用 CSS-in-JS 的原因是为了能够根据其他样式或数据计算样式。” 例如:如果背景是灰色,那么边框就是蓝色,宽度是 3px(假设是星期二)。但事实证明,得益于 calc 函数,CSS 本身就具有一定的逻辑性,而且我们仍然可以将控制权交给 CSS 团队。
纯 CSS 的确能做到很多事,这一点毋庸置疑。当你第一次看到这个calc函数时,你会惊叹不已:这简直就是实时数学逻辑,太神奇了!但随后你就会意识到,JavaScript 能访问的信息远比 CSS 多得多!CSS 无法告诉我鼠标光标的位置,也无法告诉我周围的环境光,所以它的逻辑只能局限于样式表和视口内部。
这就是为什么我们会有纯 CSS 与 JavaScript 之争,但 re.css 却有不同的看法,应该让它们彼此友好相处,发挥各自的优势,而不是让一方承担另一方的责任。
在我们继续之前,有几件事需要了解。
/* calc can be nested */
/* CSS custom properties are valid calc values */
calc( calc( var(--the-room-is-dark) * 200) - 20);
当然,你可以从 JavaScript 中传递 CSS 变量,然后用 calc 函数进行计算,我认为对于较小的计算来说是可行的。不过,上面的例子使用了“魔法数字”,理想情况下,所有值都应该是变量。
好的,看来我们已经将大部分样式逻辑移到了样式表中,但是反过来呢?我提到过,你可以在 CSS 中存储 CSS 无法理解的值,我为什么要这样做呢?
举个例子:
:root {
--current-theme: light;
--theme-text-color: #000;
--theme-bg-color: #fff;
}
CSS 无法直接使用当前主题值,但它的最佳搭档 JavaScript 可以。你的 JavaScript 代码可以设置暗黑模式,然后通过更多自定义 CSS 属性相应地切换颜色。
问题在于,媒体查询和开发者工具、支持规则和其他外部因素可能会改变 CSS 变量的值,导致 JavaScript 不同步。由于没有 onPropertyChange 事件监听器,所以我编写了一个简单而强大的库来为这些更改添加响应式(注意:您必须从 JavaScript 端处理媒体查询或鼠标悬停事件),它还有助于响应式地获取和设置 none。
想象一下,外部变化只需花费很少的成本就能触发 JavaScript 函数,从而引发一系列漂亮的样式逻辑连锁反应,这基本上就是我发布的代码(但 CSS 不能直接触发可观察对象,必须由 JS 处理,请参阅注释)。无论如何,它实现了我预期目标的 90%,而且总会有 2.0.0 版本,总之我想和你们分享一下。
一个轻量级的库,可显著提升您的样式工作流程。借助响应式 CSS 属性 (re.css),您可以设置自定义 CSS 属性,并通过 JavaScript 实时响应属性变化。
目录
你可以把现代 JavaScript 看作有两个主要职责:更新业务逻辑和更新样式。后者的问题在于它增加了额外的开销和需要克服的新问题。re.css 规定 CSS 负责更新样式,而 JavaScript 应该……
还有很多内容要讲,但这篇文章已经够长了,下次我们来做点什么,比如用 re.css 的灵感来设计一个待办事项应用。
文章来源:https://dev.to/adam_cyclones/how-to-make-css-reactive-5eol