每个前端人都经历过的一个痛处就是,在写页面 ui 样式时不停的在 html 文件(或代码区域)和 css 文件(或代码区域)之间来回切换,这种聚焦点分离让 ui 样式的开发有点点烦。原子化 css 正是这一痛处的有效的解决方案。
# 简介
原子化的优点也即原子化,因为所有书写的 css 都是以最原子的形态出现,所以可复用性无解肥。
原子化中每个 css 属性和值都有一个对应简写的 class 来实现,通常这些简写也符合认知规律,所以书写起来并没有很大心智负担,熟能生巧(唯手熟耳)。
这有点类似在 html 中书写 style,不过更加简单和快捷。比如:
w-10
就是width: 100px
mx-10
就是margin-left: 10px; margin-right: 10px;
last-mr-0
就是:last-child { margin-right: 0; }
而且通过自定义规则配置,还能实现更多的简写,如:
wh-full
就是width: 100%; height: 100%
bb-1-red
就是border-bottom: 1px solid red;
f-b
就是display: flex; justify-content: space-between; align-items: center;
在实际应用中代码如下:
<div class="inline-block h-164 bg-#F2F3F5 rounded-4 p-20 pt-16!"> | |
<div class="mb-8 text-14 text-#7A8699">示例(请按照示例上传真实、有效的集装箱照片):</div> | |
<div class="f-s"> | |
<div class="relative w-100 h-100 mr-8 last-mr-0" v-for="item in sampleBoxPics" :key="item.id"> | |
<img class="wh-full object-cover" :src="`https://filecdn.xxx.com/xxx/box_pic_${item.id}.png`" alt="" /> | |
<div class="absolute bottom-0 w-full f-c bg-#1D2129/80 text-white text-12"></div> | |
</div> | |
</div> | |
</div> |
# 安装配置(vue + vite 项目中):
安装 unocss 和工具类预设:
pnpm i -D unocss @unocss/preset-uno |
在 main.ts 中引入 uno.css
import { createApp } from 'vue' | |
import App from './App.vue' | |
import 'virtual:uno.css' | |
createApp(App).mount('#app') |
在 vite.config.ts 文件中配置
import { defineConfig } from 'vite' | |
import vue from '@vitejs/plugin-vue' | |
import UnoCSS from 'unocss/vite' | |
export default defineConfig({ | |
plugins: [ | |
vue(), | |
UnoCSS(), | |
], | |
... | |
}) |
新建 uno.config.ts 文件并配置(此处是我个人的配置偏好,可以根据喜好自己配置,或者根据项目需要配置一些常用公共样式):
// uno.config.ts | |
import { defineConfig, presetUno } from 'unocss' | |
import presetRemToPx from '@unocss/preset-rem-to-px' | |
export default defineConfig({ | |
presets: [ | |
presetUno(), | |
//unocss 默认 rem,转成 px | |
presetRemToPx({ | |
baseFontSize: 4, | |
}) as any, | |
], | |
shortcuts: { | |
'f-b': 'flex justify-between items-center', | |
'f-c': 'flex justify-center items-center', | |
'f-s': 'flex justify-start items-center', | |
'f-e': 'flex justify-end items-center', | |
'text-overflow': 'truncate', | |
'wh-full': 'w-full h-full', | |
}, | |
rules: [ | |
[/^b-(\d+)$/, match => ({ 'border-width': `${match[1]}px` })], | |
[/^b-(\d+)-#([\w]+)$/, match => ({ 'border': `solid ${match[1]}px #${match[2]}` })], | |
[/^bt-(\d+)-#([\w]+)$/, match => ({ 'border-top': `solid ${match[1]}px #${match[2]}` })], | |
[/^bb-(\d+)-#([\w]+)$/, match => ({ 'border-bottom': `solid ${match[1]}px #${match[2]}` })], | |
[/^bl-(\d+)-#([\w]+)$/, match => ({ 'border-left': `solid ${match[1]}px #${match[2]}` })], | |
[/^br-(\d+)-#([\w]+)$/, match => ({ 'border-right': `solid ${match[1]}px #${match[2]}` })], | |
[/^px-(\d+)$/, match => ({ 'padding-left': `${match[1]}px`, 'padding-right': `${match[1]}px` })], | |
[/^py-(\d+)$/, match => ({ 'padding-top': `${match[1]}px`, 'padding-bottom': `${match[1]}px` })], | |
[/^mx-(\d+)$/, match => ({ 'margin-left': `${match[1]}px`, 'margin-right': `${match[1]}px` })], | |
[/^my-(\d+)$/, match => ({ 'margin-top': `${match[1]}px`, 'margin-bottom': `${match[1]}px` })], | |
[/^pt-(\d+)$/, match => ({ 'padding-top': `${match[1]}px` })], | |
[/^pb-(\d+)$/, match => ({ 'padding-bottom': `${match[1]}px` })], | |
[/^pl-(\d+)$/, match => ({ 'padding-left': `${match[1]}px` })], | |
[/^pr-(\d+)$/, match => ({ 'padding-right': `${match[1]}px` })], | |
[/^mt-(\d+)$/, match => ({ 'margin-top': `${match[1]}px` })], | |
[/^mb-(\d+)$/, match => ({ 'margin-bottom': `${match[1]}px` })], | |
[/^ml-(\d+)$/, match => ({ 'margin-left': `${match[1]}px` })], | |
[/^mr-(\d+)$/, match => ({ 'margin-right': `${match[1]}px` })], | |
], | |
}) |
vscode 还有 UnoCSS 扩展,可以预览编译后的 class:
# 演练
有兴趣的少侠可以点击 此处 进行在线演练,零配置体验 unocss。
也可以在 这里 查看类名书写后编写的结果。
而我最常用的其实是 tailwindcss 文档,在这里可以查看各种 css 属性的书写方式(unocss 是兼容 tailwindcss 的,而 unocss 官网貌似并没有提供此类文档)。
# 缺点
原子化 css 在编写复杂的样式效果时,会造成 html 的 class 名非常长,而且 vue react 等框架中,都会有部分 js 逻辑注入 html 中,这样 html 文件会变得臃肿不堪。
原子化 css 违背了组件化的设计思想,比如你用 unocss 写了一个组件,后来发现比较通用想发包就比较麻烦了。
维护项目时,不再可以通过 css 名来定位代码位置,接手陌生项目时会比较痛苦。
# 最后
虽然存在很多问题,但是原子化带来的好处是无可比拟的。而且他让你的项目避免了很多重复混乱的 css 命名。