我创建了自己的纯 CSS 微框架,这是一个故事🙃
封面照片由 Kelly Sikkema 在 Unsplash 上拍摄
但为什么?
好吧,这是一个有趣的故事。不过,首先,如果你想了解最终结果,可以看看这个链接:https://felippe-regazio.github.io/plume-css/。我把它命名为 Plume-CSS。你可以使用 NPM、Yarn 来安装它,或者直接下载包并在文档中加载样式。点击链接了解更多信息。在这篇文章中,我想谈谈我是如何开始编写一些基本的样式和功能,并最终构建出一个微框架 S 的:
Plume-CSS?
我开始构建这个微框架是为了个人学习。但随着我编写代码时越来越兴奋,事情发展得非常快。最初的想法是创建一个 Basic CSS 文件,在启动简单小型项目时用作微型框架,或者只是作为一个快速的起点来巩固发展。规模可以像Skeleton
…… Milligram
,甚至更小。
仅需纯 CSS 和一组基本的可直接样式化的元素,仅此而已。无需大量的类,也无需 JS。唯一的区别在于 Plume 是作用域化的,样式应该应用在一个主类下。Plume 还应该为更多元素设置样式,例如进度条、仪表、复选框、单选按钮、字段集等等。我很快就完成了,但我并没有停下来。
我使用简洁的基础样式,为大量原生 HTML 元素(几乎全部)添加了样式。这些样式都应用在 class 下plume
。同一周,我撰写了一篇文章《使用 SASS/SCSS 自定义 CSS 属性 (vars)》,这是一种实用的架构策略,揭示了 SASS 架构中一些适用于可主题化项目的理念。
所以我想“嘿,Plume 也应该有主题。我应该把我上一篇文章中描述的想法应用到这项研究中”。
获得主题化
所以我把我的微型 CSS 框架改造成了一个可主题化的微型框架。我映射了基础 CSS 设计项目的主要特征,并将其转化为 :root 上的一组 CSS 自定义属性。然后我使用这些自定义属性来设置元素的样式。
我还使用自定义属性来定义元素的特定样式,例如按钮、复选框和单选按钮,并创建了诸如输入切换之类的伪输入(没错,就是纯 CSS)。最终,我得到了一组 70 多个 CSS 自定义属性,它们共同构建了框架的默认外观。如果您熟悉 CSS 自定义属性,您就会知道这代表着强大的自定义能力。
然后我想“在创建主题的同时编写代码很烦人,我们要经常修改内容,并且必须不断地覆盖代码中的许多属性,并检查是否一切正常。如果有一个带有实时视觉反馈的主题编辑器就太酷了。
主题编辑器
这是最难的部分。基本上就是一个 UI-Kit(所有样式元素都放在同一个页面上——作为演示)和一个包含表单的侧边菜单。
表单上的每个输入都控制着不同的 CSS 自定义属性。因此,当您使用主题编辑器调整属性时,该属性会被覆盖,页面样式也会自动更新,从而为您提供即时的视觉反馈。
这有点棘手,因为输入和属性之间的绑定并非硬编码。主题编辑器会从页面样式中提取 Plume-CSS,然后提取 :root 作用域中的所有 CSS 自定义属性,将它们转换为 JSON 格式,并使用此 JSON 格式构建表单。您还可以查看自动生成的主题源代码,或下载。
毕竟,我必须把主题持久化到某个地方。因为我使用的是 GitHub Pages,没有数据库,而且本地存储也不太好(如果我想把主题展示给朋友怎么办?)。解决方案是将主题持久化到 URL 中:
对于每次主题更改事件,主题编辑器都会将其状态保存在 URL 中,具体方法是:将当前表单转换为查询字符串(GET 样式),使用 lz 字符串压缩进行压缩,然后将其附加到 URL。加载页面时,我只需反转流程:获取 URL,对其进行解码,然后使用结果填写表单。现在,主题信息存储在 URL 中。
您可以通过访问本文开头的 Plume 链接并点击左上角的按钮来查看主题编辑器。左下角的按钮是您可以加载的现有主题列表。
前缀
这时我心想:“伙计,我得别再调了,跟我最初的想法相比,我已经做了很多了。” 但随后我又想到了一个问题:
如果我希望这个微框架完全覆盖范围,就不能只使用包装类。我需要给所有类、数据属性和其他选择器添加前缀,才能真正避免冲突。由于样式应用于裸元素,所有类和数据属性都只是原子实用程序,所以最好给它们添加前缀。
此外,前缀必须是可配置的。在这种情况下,最常见的方法是直接在 .scss 文件上添加前缀。考虑到这一点,我有两个选择:
- 定义输出已加前缀的选择器的混合和函数
- 仅定义一个 $prefix 变量并在代码中使用
这两种方法对我来说都很糟糕。首先,它们会在我的代码中引入一条新规则,修改一个重要的常用方法。这很糟糕。其次,它们会写出非常非常丑陋的代码。
所以,解决方案是:在编译时添加前缀。我使用 Gulp 来整合这个项目中的各个部分。这样,我就可以用它来为生成的 CSS 添加前缀:考虑到这一点,我构建了一个前缀器,然后将其转换为 gulp-prefixer。想法是:
正常编写 sass 文件,将整段代码编译为 css,并使用前缀器在编译时解析流,为所有内容添加前缀。最后保存输出。
而且它确实有效。这促使我创建了一种plume.config.js
简单的方式来配置一切。
配置文件
因此,我决定不进行任何硬编码。为此,我引入了一个简单的 plume.config.js 文件,其中包含以下选项:
module.exports = {
superclass: 'plume',
outputStyle: 'compressed',
targetDirName: 'lib',
prefixer: {
prefix: 'pm-',
ignore: ['.plume'],
}
}
超类将作为变量 $superclass 注入到 sass 文件的开头。plume
默认情况下,项目中的 sass mixin 将使用此变量来限定该类的模块范围。所以,这就是包装类。
这outputStyle
就是 sass 处理器必须输出文件的方式。targetDirName
显而易见的是:所有内容将保存在哪里。然后是前缀。
您可以选择前缀,并将选择器传递到忽略列表(高级选项包括仅添加前缀的类或仅添加数据属性)。您也可以设置prefix: false
不添加任何前缀。文档在构建时也会使用此文件和 package.json 来获取动态信息。现在只需运行一个简单的程序npm run build-all
,即可生成微框架和文档。
完成了!
哎呀,真是太多了。一件事引出了另一件事,而且我在编写所有想法时非常兴奋,所以就一直坚持写代码。这些概念和策略大多并不新鲜,但首先,这是一个学习案例。从零开始实现所有东西的感觉很棒。
结果比我想象的要好,我认为它对社区很有用,不仅可以作为 CSS 微框架(我们有很多),还可以作为参考、起点、学习示例等。
最终,我得到了一个轻量级、主题丰富、灵活且功能齐全的 CSS 微框架。正如我之前所说,我把它命名为 Plume-CSS。
Plume 采用 GPL 许可证。代码位于:
https://github.com/felippe-regazio/plume-css
安装和使用文档可以在这里找到:
https://felippe-regazio.github.io/plume-css/
我还努力记录所有内容。您可以在 GitHub 页面上找到文档。技术和开发文档位于存储库 README.md 中。您可以随意使用它,或者为它做出贡献。
文章来源:https://dev.to/felipperegazio/i-created-my-own-pure-css-micro-framework-a-tale-lcd