原子化 CSS 实践

简介: 本文介绍了 原子化 CSS 的相关背景概念、UnoCSS 的特点、用法。通过阅读本文,你可以了解如何使用 这款 CSS 引擎。

jcLee95 的 博客

邮箱 :291148484@163.com
本文由作者从原 CSDN 上迁移至阿里云

目 录


1. 概述

2. 原子化 CSS 的概念

3. 原子化 CSS 的实现实践

4. 推荐:UnoCSS 引擎 - 简介与用法


1. 概述

本文介绍了 原子化 CSS 的相关背景概念、UnoCSS 的特点、用法。通过阅读本文,你可以了解如何使用 这款 CSS 引擎。


2. 原子化 CSS 的概念

2.1 什么是原子化 CSS

所谓 原子化 CSS ,指的是一种用于CSS的架构方式的理念,它倾向于 用途单一的 class,并 以视觉效果进行命名。例如 bootstrap 的颜色系统,为我们提供了直观的颜色名称:

我们可以将这些名称以相似的命名方式构建 css 类:

// Background color
.bg-blue-100 { background-color: $blue-100 }
.bg-blue-200 { background-color: $blue-200 }
.bg-blue-300 { background-color: $blue-300 }
.bg-blue-400 { background-color: $blue-400 }
.bg-blue-500 { background-color: $blue-500 }
.bg-blue-600 { background-color: $blue-600 }
.bg-blue-700 { background-color: $blue-700 }
.bg-blue-800 { background-color: $blue-800 }
.bg-blue-900 { background-color: $blue-900 }
// Font color
.ft-blue-100 { color: $blue-100 }
.ft-blue-200 { color: $blue-200 }
.ft-blue-300 { color: $blue-300 }
.ft-blue-400 { color: $blue-400 }
.ft-blue-500 { color: $blue-500 }
.ft-blue-600 { color: $blue-600 }
.ft-blue-700 { color: $blue-700 }
.ft-blue-800 { color: $blue-800 }
.ft-blue-900 { color: $blue-900 }
// margin
.m-1 { margin: 0.25 rem; }
.m-2 { margin: 0.5 rem; }
.m-3 { margin: 0.75 rem; }
.m-4 { margin: 1 rem; }
.m-5 { margin: 1.25 rem; }
.m-6 { margin: 1.5 rem; }
.m-7 { margin: 1.75 rem; }
.m-8 { margin: 2 rem; }
.m-9 { margin: 2.25 rem; }

我们可以很直观地使用和调整这些变量值来满足我们实际开发中的需求,同时我们可以通过动控制 DOM 的样式来轻松地对效果进行切换,这在 一些现代前端框架(如vue)中,都可以有很丝滑的体验。

这个例子中的变量为 scss/sass(Sass) 变量,Sass 是目前最强大的前端样式预编译语言,本文在后文中也会有一些涉及它的内容。如果你只会 css,或者还在使用 Less(另一种流行的预编译语言),那么建议你尽早学一下 scss 语法,这十分强大方便,bootstrap、elementPlus 等等多数当前主流框架早以切换到其构建样式系统。

2.2 为什么推荐原子化 CSS

那么为什么要原子化呢。很显然是让代码更 直观可读。另外一方面,从设计师的角度出发,如果我们拿到下面这个语义化的外边距变量名:

.p-1 { margin: 0.25 rem; }
.p-2 { margin: 0.5 rem; }
/* ... */
.p-9 { margin: 2.25 rem; }

完全就可以对照着呈现效果自己手动更改变量来完成效果切换!


3. 原子化 CSS 的实现实践

3.1原子化初体验

如何才能具备原子化的理念的,实现方法有很多。在一个大项目中为了原子化 CSS,。可以先 提供所有你可能需要用到的 CSS 工具,例如 外边距的大小工具——我们需要约定好一套规范,就像 2.2 小节中的代码那样,使用 p 表示 padding 的简写,使用 数字 1、2、3、… 表示基值的倍数,这里约定基值为 0.25 rem

很显然在现实项目中通过手动列举 CSS 类名并逐个描述来完成一套这样的约定是麻烦的,比如在这种情况下为了尽可能简单一点我们会使用 root 为元素中定义一些CSS变量——它们会在不同的原子类中反复用到:

:root {
  --blue-100: #CEE1FE;
  --blue-200: #9DC3FC;
  --blue-300: #69A1F3;
  --blue-400: #3C89FA;
  --blue-500: #0D6DFB;
  --blue-600: ##0A58CA;
  --blue-700: #084297;
  --blue-800: #052C65;
  --blue-900: #031633;
  --rsize-1: 0.25 rem;
  --rsize-2: 0.5 rem;
  --rsize-3: 0.75 rem;
  --rsize-4: 1 rem;
  --rsize-5: 1.25 rem;
  --rsize-6: 1.5 rem;
  --rsize-7: 1.75 rem;
  --rsize-8: 2.00 rem;
  --rsize-9: 2.25 rem;
}

然后施展我们的拳脚:

// Background color
.bg-blue-100 { background-color: var(--blue-100) }
.bg-blue-200 { background-color: var(--blue-200) }
// ...
.bg-blue-900 { background-color: var(--blue-200) }
// Font color
.ft-blue-100 { color: var(--blue-100) }
.ft-blue-200 { color: var(--blue-200) }
// ...
.ft-blue-900 { color: var(--blue-900) }
// Margin
.m-1 { margin: var(--rsize-1) }
.m-2 { margin: var(--rsize-1) }
// ...
.m-9 { margin: var(--rsize-9) }

3.2 使用预编译语言

由于 CSDN 现在仍然不至于预编译语言,相关代码附上高亮截图。

这样是不是依然很麻烦——好在我们可以通过编程来完成。

由于 css 自身并没有这样的能力,以前不得不借助其它语言来生成这样的东西,但如今我们可以使用 如 Sass、Less 这样的预处理器来实现。例如生成 10

p-1p-2、…、p-9,我们可以使用 @for 指令:

@for $i from 1 through 9 {
  .m-#{$i} {
    margin: $i / 4 rem;
  }
}


e000fd779cc04a979b35d7ee7c4fbb3b.png


上面的 @for 指令可以在限制的范围内重复输出格式,其语法格式为:

@for $var from <start> through <end> {
  // ... style
}

或者

@for $var from <start> to <end> {
  // ... style
}

其中:

  • $var 是迭代变量,可以在块内通过 {$var} 的格式来引用;
  • 当使用 through 时,条件范围包含 的值,而使用 to 时条件范围只包含 的值不包含 的值;
  • 和 必须是整数值。

对于颜色值的计算和处理要复杂一些,我们需要用到一些 Sass 内置的一些颜色处理函数,例如 mixadjust-huechange-colorscale-colordesaturatetransparentize等等,有兴趣的读者可以看我的另外一篇文章 《sass笔记 - 实战中颜色的玩法总结》。我们可以在 Sass 内置函数的基础上进行二次封装为我们的自定义 Sass 函数,例如:

/** 增加一个颜色的亮度 */
@function tint-color($color, $weight) {
  @return mix(white, $color, $weight*1%);
}
/** 降低一个颜色的亮度 */
@function shade-color($color, $weight) {
  @return mix(black, $color, $weight*1%);
}
/** 如果权重为正,则阴影,否则着色 */
@function shift-color($color, $weight) {
  @return if($weight > 0, shade-color($color, $weight*1%), tint-color($color, -$weight*1%));
}

这样我们可以使用一个基础颜色,调用颜色改变函数获得更多不同的颜色应用于更多的CSS类中实现原子化。

例如使用不同的着色百分比给蓝色进行:

$deep-blue: #0000a0;     // 一个基础颜色
@for $i from 1 through 100 {
  .bg-perct-blue-#{$i} {
    background-color: tint-color($deep-blue, $i);
  }
}

经过编译,会产生以下形式的 CSS 类:

可以看到,仅仅通过少量的代码就生成了一百个 色阶型 的 原子类。


4. UnoCSS - 一款原子化CSS引擎

4.1 UnoCSS 简介与安装

原子化的另外一个决绝方案就是实用一些 JavaScript 模块了,这有时候也是很方便的,比如 Windi CSSTailwind CSS 以及本节我们打算介绍的 UnoCSS。 其中UnoCSS是一款原子化的即时按需 CSS 引擎,其中没有核心实用程序,所有功能都是通过预设提供的。默认情况下 UnoCSS 应用通过预设来实现相关功能。以下是其官方预设:

预设 描述
@unocss/preset-uno 默认预设(现在等效于 @unocss/preset-wind )。
@unocss/preset-mini 最小化但必不可少的规则和变体。
@unocss/preset-wind ailwind / Windi CSS CSS紧凑预设。
@unocss/preset-attributify 为其他预设和规则提供归因模式。
@unocss/preset-icons 使用任何图标作为类实用程序。
@unocss/preset-web-fonts 轻松使用网络字体。
@unocss/preset-typography 版式预设。
@unocss/preset-tagify UnoCSS 的标记模式。
@unocss/preset-rem-to-px 将 rem 转换为 px for utils。

我们可以通过 npm、yarn、pnpm 等工具(任选一种)安装到你的项目中:

npm i -D unocss
# or
yarn add -D unocss
# or
pnpm i unocss -D

4.2 预设(Presets)的使用

对于 vite 项目,可以在你项目 vite.config.ts 配置文件中使用 UnoCSS 的vite插件:

// vite.config.ts
import UnoCSS from 'unocss/vite'
import { presetAttributify, presetUno } from 'unocss'
export default {
  plugins: [
    UnoCSS({
      presets: [
        presetAttributify({ /* 预设选项 */}),
        presetUno(),
        // ...自定义预设
      ],
    }),
  ],
}

其中当指定预设选项时,默认预设将被忽略。因此如果想要禁用默认预设,可以将设置为空的预设数组。

4.3 自定义规则(Rules)

自定义静态规则

你可以通过以下方式自定义一个简单的 UnoCSS 静态规则:

rules: [
  ['m-1', { margin: '0.25 rem' }],
  ['m-2', { margin: '0.5 rem' }],
  // ...
  ['m-9', { margin: '2.25 rem' }],
]

每当在用户的代码库中检测到m-1m-2、… 这些名称时,如在

<div class="m-1">My Button</div>
<div class="m-2">My Button</div>
<!-- ... -->
<div class="m-9">My Button</div>

就会生成以下CSS:

.m-1 { margin: 0.25 rem; }
.m-2 { margin: 0.5 rem; }
// ...
.m-9 { margin: 2.25 rem; }

自定义动态规则

更多的情况乱下我们通过正则表达式表示我们的规则会更加实用和方便一些:

rules: [
  [/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4} rem` })],
]

这样也避免了枚举,比如我们要用到 .m-100 ,显然这样的场景下就需要通过正则表达式定义动态规则的方法来实现了。

目录
相关文章
|
7月前
|
Web App开发 前端开发 JavaScript
CSS实践详解总结
CSS实践详解总结
99 0
|
7月前
|
前端开发
【第18期】一文读懂原子CSS框架
【第18期】一文读懂原子CSS框架
231 0
|
5月前
|
前端开发 开发者
通过实践来提升CSS动画技能是非常重要的
【7月更文挑战第1天】通过实践来提升CSS动画技能是非常重要的
36 1
|
7月前
|
存储 移动开发 前端开发
使用HTML5和CSS3构建现代网页:技术详解与实践
【5月更文挑战第28天】本文详细介绍了使用HTML5和CSS3构建现代网页的技术与实践。HTML5新增语义化标签、多媒体支持、本地存储和表单验证等功能,提升了网页开发效率和用户体验。CSS3则带来了更多选择器、盒模型改进、背景与边框样式以及动画过渡效果,使网页设计更具视觉冲击力。通过实例展示了如何结合两者创建结构清晰、交互丰富、响应式的现代网页。
|
7月前
|
前端开发
实践任务:项目介绍与项目准备+制作网页头部和导航+制作banner和最新更新栏目+制作苹果之家栏目+制作底部版权区域与CSS代码优化+制作Apple独家栏目
实践任务:项目介绍与项目准备+制作网页头部和导航+制作banner和最新更新栏目+制作苹果之家栏目+制作底部版权区域与CSS代码优化+制作Apple独家栏目
48 1
|
7月前
|
移动开发 缓存 前端开发
【专栏:HTML与CSS实践篇】网页性能优化:CSS与HTML的最佳实践
【4月更文挑战第30天】本文探讨了优化CSS和HTML以提升网页性能的最佳实践。HTML优化包括:精简结构、压缩代码、异步加载脚本和利用缓存。CSS优化则涉及:精简代码、合并文件、使用CSS Sprite、善用CSS3属性、避免@import及响应式设计。这些方法能加快加载速度,改善用户体验。
94 6
|
7月前
|
移动开发 前端开发 JavaScript
:掌握移动端开发:HTML5 与 CSS3 的高效实践
:掌握移动端开发:HTML5 与 CSS3 的高效实践 “【5月更文挑战第6天】”
100 1
|
7月前
|
移动开发 前端开发 UED
【专栏:HTML与CSS前端技术趋势篇】渐进式增强与优雅降级在前端开发中的实践
【4月更文挑战第30天】前端开发中的渐进式增强和优雅降级是确保跨浏览器、跨设备良好用户体验的关键策略。渐进式增强是从基础功能开始,逐步增加高级特性,保证所有用户能访问基本内容;而优雅降级则是从完整版本出发,向下兼容,确保低版本浏览器仍能使用基本功能。实践中,遵循HTML5/CSS3规范,使用流式布局和响应式设计,检测浏览器特性,并提供备选方案,都是实现这两种策略的有效方法。选择合适策略优化网站,提升用户体验。
120 4
|
7月前
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS实践篇】CSS框架(Bootstrap/Foundation)快速上手
【4月更文挑战第30天】Bootstrap和Foundation是两种流行的CSS框架,用于构建响应式网页。它们包含预定义的样式、栅格系统和组件,加速开发流程。Bootstrap以其12列栅格系统闻名,而Foundation提供更定制化和模块化选项。了解并熟练运用这些框架的基本概念和组件,结合最佳实践和性能优化,能帮助开发者高效创建符合现代设计趋势的网页项目。
136 3
|
7月前
|
编解码 前端开发 UED
【专栏:HTML 与 CSS 实践篇】网页图标与字体图标的使用
【4月更文挑战第30天】本文探讨了网页设计中两种主要图标形式——传统图标和字体图标。传统图标(PNG, JPEG, GIF)视觉效果丰富但文件大,易影响加载速度且维护不便。字体图标占用空间小,易于维护和定制,但视觉效果相对简单,选择有限。实际应用中,两者可结合使用,以导航栏、操作按钮和提示信息为例说明了图标的重要性。设计师需注意兼容性、清晰度和性能优化问题,根据项目需求选择合适图标类型,以提升网页质量和用户体验。
92 3