一、什么是原子化CSS (Atomic CSS) ?
我们平时写的普通样式
而原子化CSS
原子化 CSS定义: 一种 CSS 的架构方式,它倾向于小巧且用途单一的 class,并且会以视觉效果进行命名。
由此可见,定义一些细粒度,离散化,独立的 class,这就是原子化 CSS框架的设计方式。
二、原子化CSS优点是什么?
1.可读性和可维护性
2.灵活性
3.可重用性
预测如果使用会发生什么改变?
开发上:节省很多写样式的时间,提升开发体验。
生产上:打包出来的样式代码占比将突然骤降然后趋于不变。
市面上流行的原子化CSS框架:
- Tailwind CSS --鼻祖 https://tailwindcss.com/
- Windi CSS https://cn.windicss.org/
- unoCSS https://github.com/unocss/unocss ,https://unocss.dev/
1.Tailwind CSS
- 性能瓶颈:
Tailwind 本质上就是一个 postcss 插件,通过 AST 来分析 css 代码,对 css 做增删改,并且通过他自己的 extractor 提取 js、html 中的 class,之后基于这些来生成最终的 css 代码。 - 体积问题:
Tailwind 生成了全量 数 MB 的 CSS,使得加载与更新 CSS有性能问题。(所以后续出了JIT模式按需引擎。)
下面有个例子:
这时候你可以直接使用 class=“m-1” 来设置边距。
即使你只使用了其中一条 CSS 规则,但还是要为其余几条规则的文件体积买单。
如果之后你还想支持不同的 margin 方向,使用比如 mt 代表 margin-top,mb 代表 margin-bottom 等,加上这 4 个方向以后,你的 CSS 大小会变成原来的 5 倍。
如果再有使用到像 :hover 和 :focus 这样的伪类时,体积还会得更变大。
解决方案:JIT模式。
-
额外配置的局限性
例子: border-10 不起作用
解决方案:进行额外配置,每配置一种,查询一次文档
-
添加自定义工具的噩梦
Tailwind 的 API 和插件系统沿用了旧的思维方式进行设计,并不能适应新的按需方式。
Windi CSS:
Windi CSS 是从零开始编写的 Tailwind CSS 的替代方案。零依赖,也不要求用户安装 PostCSS 和 Autoprefixer,自己编写了一个自定义解析器和AST。更为重要的是,它支持 按需生成。Windi CSS 不会一次生成所有的 CSS,而是只会生成你在代码中实际使用到的原子化 CSS。
Windi 需要与 Tailwind 兼容,它还必须使用与 Tailwind 完全相同的配置项,虽然解决了数字问题,自定义工具的配置是和 Tailwind 一样的。
unoCSS强大之处
UnoCSS 是一个引擎,而非一款框架,因为它并未提供核心工具类,所有功能可以通过预设和内联配置提供。
- 极致性能
比Tailwind CSS JIT引擎快3.7倍左右 (最初快200倍
2. 完全可定制
相比于 Tailwind CSS 必须把原子类写到 class 里面, UnoCSS 提供了更多可选方案,并且兼容多种风格的原子类框架,除了 Tailwind CSS,同样支持 Bootstrap, Tachyons,Windi CSS
- 属性化模式 (Attributify Mode)
<button class="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono font-light py-2 px-4 rounded border-2 border-blue-200 dark:bg-blue-500 dark:hover:bg-blue-600">
Button
</button>
<!-- 经过配置,你可以这么写: -->
<button
bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"
text="sm white"
font="mono light"
p="y-2 x-4"
border="2 rounded blue-200"
>
Button
</button>
<div class="m-2 rounded text-teal-400" />
<!-- 经过配置,你可以这么写: -->
<div m-2 rounded text-teal-400 />
- 前缀组
<div class="hover:bg-gray-400 hover:font-medium font-light font-mono"/>
<!-- 经过配置,简化之后: -->
<div class="hover:(bg-gray-400 font-medium) font-(light mono)"/>
- 快捷方式和指令
Tailwind CSS 有指令系统,其中的 @layer components 指令可以把通用的样式 layer 到一个类上:
@layer components {
.btn-blue {
@apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded;
}
}
经过配置,unoCss可以更牛逼的动态实现
shortcuts: [
// you could still have object style
{
btn: 'py-2 px-4 font-semibold rounded-lg shadow-md',
},
// dynamic shortcuts
[/^btn-(.*)$/, ([, c]) => `bg-${c}-400 text-${c}-100 py-2 px-4 rounded-lg`],
]
并且也可以使用指令 @apply
<div class="complex-node">
我的样式很复杂的
</div>
<button class="btn">查询</button>
<button class="btn">提交</button>
<button class="btn">取消</button>
<style>
.complex-node {
@apply text-lg text-pink-400 font-bold border-1 border-gray border-dashed rounded flex flex-warp items-center justify-evenly;
}
.btn {
@apply text-green-500 rounded hover:text-lg shadow-md;
}
- 构建合并多个原子类到一个类
经过配置,通过 :uno: 标记,可以最终编译为一个类
<div class=":uno: text-center sm:text-left">
<div class=":uno: text-sm font-bold hover:text-red"/>
</div>
编译之后
<div class="uno-qlmcrp">
<div class="uno-0qw2gr"/>
</div>
.uno-qlmcrp {
text-align: center;
}
.uno-0qw2gr {
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 700;
}
.uno-0qw2gr:hover {
--un-text-opacity: 1;
color: rgba(248, 113, 113, var(--un-text-opacity));
}
@media (min-width: 640px) {
.uno-qlmcrp {
text-align: left;
}
}
- 检查器,可以详细的预览我们项目中的所有原子类
- 老项目使用方案
UnoCSS 提供了 CDN 版本,在前端的入口 index.html 文件中添加一行代码就可以支持,并且还支持配置
<script src="https://cdn.jsdelivr.net/npm/@unocss/runtime"></script>
<script>
// pass unocss options
window.__unocss = {
rules: [
// custom rules...
],
presets: [
// custom presets...
],
// ...
}
</script>
- VS Code 插件
- 预设icon,自定义配置icon
轻松集成纯 CSS 图标,不需要任何 JavaScript,UI 自己设计的图标也可以轻松集成。
(与可变修饰结合,你甚至可以根据悬停状态或颜色模式来切换图标。)
解决其他框架的痛点
- 直观且完全可定制
如需为 UnoCSS 创建一个自定义规则,你可以这样写:
静态规则
rules: [
['m-1', { margin: '0.25rem' }]
]
动态规则
rules: [
[/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
[/^p-(\d+)$/, match => ({ padding: `${match[1] / 4}rem` })],
]
现在,你只需要使用相同的模式添加更多的实用工具类,你就拥有了属于自己的原子化 CSS
- 可变修饰(Variants)
variants: [
// 支持所有规则的 `hover:`
{
match: s => s.startsWith('hover:') ? s.slice(6) : null,
selector: s => `${s}:hover`,
},
// 支持 `!` 前缀,使规则优先级更高
{
match: s => s.startsWith('!') ? s.slice(1) : null,
rewrite: (entries) => {
// 在所有 CSS 值中添加 ` !important`
entries.forEach(e => e[1] += ' !important')
return entries
},
}
]
- 预设
默认的 @unocss/preset-uno 预设 是一系列流行的原子化框架的 通用超集,包括了 Tailwind CSS,Windi CSS,Bootstrap,Tachyons 等。
例如,ml-3(Tailwind),ms-2(Bootstrap),ma4(Tachyons),mt-10px(Windi CSS)均会生效。
(你可以将自己的自定义规则和可变修饰打包成预设,与他人分享,或是使用 UnoCSS 作为引擎创建你自己的原子化 CSS 框架!)
// my-preset.ts
import { Preset } from 'unocss'
export const myPreset: Preset = {
name: 'my-preset',
rules: [
[/^m-([\.\d]+)$/, ([_, num]) => ({ margin: `${num}px` })],
[/^p-([\.\d]+)$/, ([_, num]) => ({ padding: `${num}px` })],
],
variants: [/* ... */],
shortcuts: [/* ... */],
// ...
}
// uno.config.ts
import { defineConfig } from 'unocss'
import { myPreset } from './my-preset'
export default defineConfig({
presets: [
myPreset, // your own preset
],
})
实际使用&集成
资料搬运:
1.https://antfu.me/posts/reimagine-atomic-css-zh
2.https://mp.weixin.qq.com/s/vAHdUQwCN-J815iIYuyAeA
3.https://mp.weixin.qq.com/s/kl8Dwo_jFGRU2VwE3Vn62g