原子化 CSS 实践

news2024/11/24 2:50:10


原子化 CSS 实践

jcLee95 的CSDN 博客
邮箱 :291148484@163.com
CSDN 主页https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址https://blog.csdn.net/qq_28550263/article/details/129178547

目 录

1. 概述

2. 原子化 CSS 的概念

  • 2.1 什么是原子化 CSS
  • 2.2 为什么推荐原子化 CSS

3. 原子化 CSS 的实现实践

  • 3.1原子化初体验
  • 3.2 使用预编译语言

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

  • 4.1 UnoCSS 简介与安装
  • 4.2 预设(Presets)的使用
  • 4.3 自定义规则(Rules)
    • 自定义静态规则
    • 自定义动态规则

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 使用预编译语言

这样是不是依然很麻烦——好在我们可以通过编程来完成。
由于 css 自身并没有这样的能力,以前不得不借助其它语言来生成这样的东西,但如今我们可以使用 如 Sass、Less 这样的预处理器来实现。例如生成 10
p-1p-2、…、p-9,我们可以使用 @for 指令:

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

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

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

或者

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

其中:

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

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

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

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

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

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

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

4.1 UnoCSS 简介与安装

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

预设描述
@unocss/preset-uno默认预设(现在等效于 @unocss/preset-wind )。
@unocss/preset-mini最小化但必不可少的规则和变体。
@unocss/preset-windailwind / Windi CSS CSS紧凑预设。
@unocss/preset-attributify为其他预设和规则提供归因模式。
@unocss/preset-icons使用任何图标作为类实用程序。
@unocss/preset-web-fonts轻松使用网络字体。
@unocss/preset-typography版式预设。
@unocss/preset-tagifyUnoCSS 的标记模式。
@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 ,显然这样的场景下就需要通过正则表达式定义动态规则的方法来实现了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/365793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter+【三棵树】

定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴&#xff1a;Elements和RenderObjects&#xff1b;由于它们都是有着树形结构&#xff0c;所以经常会称它们为三棵树。 这三棵树分别是&#xff1a;Widget、Element、RenderObject Widget树&#xff1a;寄存烘托内容…

代码随想录---二叉树的总结和二叉树的定义

二叉树的种类&#xff1a; 满二叉树&#xff1a;树的所有节点都是满&#xff0c;即都有左右孩子。 这棵二叉树为满二叉树&#xff0c;也可以说深度为k&#xff0c;有2^k-1个节点的二叉树。 完全二叉树&#xff1a;完全二叉树的定义如下&#xff1a;在完全二叉树中&#xff0c…

数据结构—堆(完全解析)

数据结构—堆&#xff08;完全解析&#xff09; 数据结构——堆&#xff08;Heap&#xff09;大根堆、小根堆 详解数据结构——堆 堆的基本存储 【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆 【堆/排序】堆排序的两种建堆方法 【算法】排序算法之堆排序 C…

【Tips】通过背数据了解业务

学习资料&#xff1a;做了三年数据分析&#xff0c;给你的几点建议 1. 通过背数据了解业务 原文&#xff1a; 总结&#xff1a; 方法&#xff1a;每天早上去到公司第一件事情就是先背一遍最新的各种指标。原理&#xff1a; 数据敏感性就是建立在对数据的了解和熟悉上。业务的…

使用Autoware标定工具包联合标定相机和激光雷达

前面文章介绍了&#xff0c;安装autoware标定工具包、ros驱动usb相机、robosense-16线激光雷达的使用&#xff0c;本文记录使用Autoware标定工具包联合标定相机和激光雷达的过程。1.ros驱动相机&#xff0c;启动相机&#xff1b;启动激光雷达2.联合录制bag包rosbag record -a 参…

由浅入深了解超文本传输协议http

什么是超文本传输协议&#xff1f; 超文本传输协议&#xff08;英语&#xff1a;HyperText Transfer Protocol&#xff0c;缩写&#xff1a;HTTP&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。 通过HTTP或HTTPS协议请求…

8年测开经验面试28K公司后,吐血整理出1000道高频面试题和答案

1、python的数据类型有哪些 答&#xff1a;Python基本数据类型一般分为&#xff1a;数字、字符串、列表、元组、字典、集合这六种基本数据类型。 浮点型、复数类型、布尔型(布尔型就是只有两个值的整型)、这几种数字类型。列表、元组、字符串都是序列。 2、列表和元组的区别 答…

postgresql 数据库 主从切换 测试

postgresql 数据库 主从切换 测试 文章目录postgresql 数据库 主从切换 测试前言环境&#xff1a;主从切换1. 查看数据库状态&#xff1a;2. 备库切换主库3. 旧主库切换成备库&#xff1b;4 查看状态后记前言 因数据库等保需要&#xff0c;需要对老系统的数据库进行主从切换来…

【企业云端全栈开发实践-2】Spring Boot Controller

本节目录一、Web入门二、控制器1、Controller2、RestController3、路由映射4、Method匹配5、参数传递6、entity实体层一、Web入门 Spring Boot将传统Web开发的mvc、json、tomacat等框架整合&#xff0c;提供了spring-boot-starter-web组件&#xff0c;简化了Web的应用配置。 …

一条推送的背后运营逻辑

每天我们的手机都收到大量信息&#xff0c;大多来自各APP的推送。每收到一条推送&#xff0c;不只是收到了一串简单的文字&#xff0c;背后还有一系列的隐藏逻辑。几年前我也做过“推送背后的女人”……&#xff08;其实就是干过APP消息推送运营啦~^^~&#xff09;今天就来分享…

【Java 面试合集】String, StringBuffer和StringBuilder 之间的不同

String&#xff0c; StringBuffer和StringBuilder 之间的不同 1. 概述 嗨&#xff0c;大家好【Java 面试合集】又来了&#xff0c;今天我们分享的主题是String&#xff0c; StringBuffer和StringBuilder 之间的不同。 大家别看这个知识点不难&#xff0c;但是里面的细知识很多…

利用Python实现局部异常因子(LOF)的计算

1 LOF算法 局部异常因子(Local Outlier Factor&#xff0c;LOF)算法是目前比较常用的离群点检测算法&#xff0c;该算法通过一种模糊的手段来判断数据对象是否为异常点。 对象ppp的kkk距离&#xff1a;在数据集DDD中&#xff0c;将对象ppp与距其第kkk远的对象ooo之间的距离定义…

(二十四)、实现评论功能(4)【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】

1&#xff0c;创建reply回复页面 1.1 在comment-item子组件中添加click <view class"comment-item" click"goReply">1.2 methods中添加点击跳转回复页面的方法 //跳转去回复页面goReply() {uni.navigateTo({url: "/pages/reply/reply"})}…

Linux 基础知识之权限管理

目录一、权限的认识二、用户切换三、文件权限1.三类文件访问者2.文件权限类型3.文件访问权限4.文件权限值表示一、权限的认识 权限是对用户所能进行的操作的限制&#xff0c;如果不对用户作出限制&#xff0c;那么碰到恶意用户&#xff0c;就会损害其他用户的利益。 Linux是多用…

最新文件快递柜系统网站源码-Fastapi+Sqlite3+Vue2+ElementUI-简洁好用

## 主要特色 - [x] 轻量简洁:Fastapi+Sqlite3+Vue2+ElementUI - [x] 轻松上传:复制粘贴,拖拽选择 - [x] 多种类型:文本,文件 - [x] 防止爆破:错误次数限制 - [x] 防止滥用:IP限制上传次数 - [x] 口令分享:随机口令,存取文件,自定义次数以及有效期 - [x] 匿名分享:无…

机器学习算法竞赛实战:如何看到机器学习竞赛问题?

机器学习算法竞赛实战-竞赛问题建模 更新《机器学习算法竞赛实战》一书的阅读笔记&#xff0c;更多详细的内容请阅读原书。本文的主要内容包含&#xff1a; 竞赛问题的3个主要部分-如何理解竞赛问题机器学习的样本选择如何线下评估模型实战案例 公众号&#xff1a;尤而小屋作…

scheduling Request(SR)

欢迎关注同名微信公众号“modem协议笔记”。 UE上报BSR&#xff0c;期望网络参照BSR&#xff0c;下发UL grant给UE以便发送UL data&#xff0c;正常情况下&#xff0c;整个过程都会比较顺利。但是世事难料&#xff0c;网络难免有自己的小脾气或者发送BSR不太顺畅&#xff0c;导…

通过Buildroot自制根文件系统

前言根文件系统是Linux内核启动之后读取的一个文件系统&#xff0c;并从这个文件系统中加载第一个init应用程序并启动&#xff0c;就是Linux上俗称的root进程、根进程制作它的方式有很多&#xff0c;例如busybox、yocto&#xff0c;但是这两个方式有缺点&#xff0c;第一个是bu…

JVM级别内存屏障如何禁止指令重排序的

承接上文证明CPU指令是乱序执行的当多个cpu访问同一份数据的时候怎么保证数据的一致性&#xff1f;在最底层级别的控制有好多种&#xff1a;第一种叫关中断&#xff0c;就是访问任何数据的时候必须有一个中断信号量的存在。很多传统的cpu就是靠它实现的&#xff0c;从内存读东西…

高速风筒的IPM模块解决方案

高速吹风筒是利用高转速产生的大风量来快速吹干头发&#xff0c;同时&#xff0c;高转速也使得电机与叶轮的体积缩小&#xff0c;便于设计出灵巧便携的外形。12万转的高速风筒的整体解决方案&#xff0c;满足高速吹风筒的所有应用场景&#xff0c;让客户用芯能的功率器件能更快…