TOC
前言
前端css方案有很多,从最早的bootstrap到tailwind,中间经历了各种解决方案,如scss、less、css module、style-components、emotion等。到现在风靡整个前端的tailwindcss,它们在不同的场景中具有各自的优点,我们在使用中应结合项目选择合适解决方案。
UnoCSS:一个最新的css方案,它是一个即时原子CSS引擎,设计为灵活和可扩展。在本文中我们将介绍如何在nextjs
中集成UnoCSS
,并使用UnoCSS icon
方案替换传统的icon
方案实现图标样式的极致的优化。
准备
确保已经使用create-next-app创建了一个基础应用:
pnpm dlx create-next-app@latest
根据命令行提示,选择您喜欢的配置,在本示例流程中我们选择如下:
What is your project named? next-mdx-app
Would you like to use TypeScript? No / Yes√
Would you like to use ESLint? No / Yes√
Would you like to use Tailwind CSS? No / Yes√
Would you like to use `src/` directory? No√ / Yes
Would you like to use App Router? (recommended) No / Yes√
Would you like to customize the default import alias (@/*)? No / Yes√
What import alias would you like configured? @/*
Note
选择Tailwind CSS是为了方便后续使用
UnoCSS
直接进行替换,当然也可以不选择,直接集成UnoCSS
,原理都一样,操作上只是少了移除tailwindcss
的流程。
开始
首先移除tailwindcss
依赖
pnpm remove tailwindcss
安装UnoCSS
相关依赖
pnpm add -D unocss @unocss/postcss
创建 uno.config.ts
文件,并配置样式预设
// uno.config.ts
import { defineConfig, presetUno } from "unocss";
export default defineConfig({
// ...UnoCSS options
presets: [presetUno()],
});
在 globals.css
移除tainwindcss
相关代码,然后导入重置浏览器默认样式行为文件,这里选择 tailwindcss
样式重置文件,同时导入unocss
样式
+ @import "@unocss/reset/tailwind.css";
+ @unocss all;
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
- @layer utilities {
- .text-balance {
- text-wrap: balance;
- }
- }
修改postcss.config.js
配置,移除tailwindcss
配置
module.exports = {
plugins: {
- tailwindcss: {},
- autoprefixer: {},
+ '@unocss/postcss': {
+ content: [
+ "./pages/**/*.{js,ts,jsx,tsx,mdx}",
+ "./components/**/*.{js,ts,jsx,tsx,mdx}",
+ "./app/**/*.{js,ts,jsx,tsx,mdx}",
+ ],
+ },
},
}
到此时我们已经完成了使用UnoCSS
替换tailwindcss
全部流程,现在我们来看看最终效果
pnpm dev
在浏览器中访问http://localhost:3000
,发现没有,此时的页面和初始时使用tainwindcss
样式一样,我们可以使用UnoCSS
无缝替换tailwindcss
。
这里,细心的朋友会发现,我们在globals.css
中删除了tailwindcss
的部分代码,以及在tailwind.config.ts
文件中的主题扩展还未迁移,为什么样式上没有差异呢?这是因为这两处样式本就是tailwindcss
的样式预置之一,这里是为了作为示例展示给我们。当然在UnoCSS
也有对应的配置方式,即在uno.config.ts
文件中作如下处理:
// uno.config.ts
import { defineConfig, presetUno, presetAttributify } from "unocss";
export default defineConfig({
// ...UnoCSS options
presets: [presetUno(), presetAttributify()],
// 迁移 tailwindcss 的主题配置
theme: {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic":
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
},
// 迁移 globals.css 的工具类配置
rules: [["text-balance", { "text-wrap": "balance" }]],
});
最后,删除tailwind.config.ts
文件,此时就完成了tailwindcss
的替换。
Note
这里添加了一个presetAttributify预置配置,是为了启用属性模式。这样可以更方便在代码中使用样式,并在主题配置中使用驼峰命令。
Tip
在这里您也可以作其它主题属性进行扩展,也可以定义其它的额外样式,具体请参阅UnoCSS配置。
UnoCSS 图标
Tip
推荐阅读:聊聊纯 CSS 图标
一个可以使用任意的,纯CSS的,并集成于UnoCSS
的图标解决方案,它遵循以下使用约定:
<prefix><collection>-<icon>
<prefix><collection>:<icon>
例如:
<!-- A basic anchor icon from Phosphor icons -->
<div class="i-ph-anchor-simple-thin" />
<!-- An orange alarm from Material Design Icons -->
<div class="i-mdi-alarm text-orange-400" />
<!-- A large Vue logo -->
<div class="i-logos-vue text-3xl" />
<!-- Sun in light mode, Moon in dark mode, from Carbon -->
<button class="i-carbon-sun dark:i-carbon-moon" />
<!-- Twemoji of laugh, turns to tear on hovering -->
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
除了命名规则外,其使用方式与tailwindcss
的样式规则使用方式一样。
安装
由于在unocss
包中已经包括了图标的预设,这里只需安装相应的图标库即可:
pnpm add -D @iconify-json/[the-collection-you-want]
[the-collection-you-want]
为Iconify图标的数据源的名称占位。例如,@iconify-json/ri对于Remix Icon、@iconify-json/heroicons对于heroicons。您可以参考Icones或Iconify了解所有可用的集合。
然后在uno.config.ts
文件中添加图标预设
// uno.config.ts
import { defineConfig, presetIcons } from 'unocss';
export default defineConfig({
presets: [
presetIcons({ /* options */ }),
// ...other presets
],
})
额外属性
配置图标额外属性,使其在实际样式应用中水平居中显示。
presetIcons({
extraProperties: {
'display': 'inline-block',
"vertical-align": "-.125em",
// ...
},
})
自定义图标
在图标预设中添加自定义图标,如下配置,然后,你可以在你的 html 上使用它:<span class="i-custom:circle"></span>
presetIcons({
collections: {
custom: {
circle: '<svg viewBox="0 0 120 120"><circle cx="60" cy="60" r="50"></circle></svg>',
/* ... */
},
}
})
完成上述配置后,我们就可以在html
中的任何地方自由的使用图标样式啦,不同于传统的图标使用方式,使用UnoCSS icon
只需在标签上写上对应图标的样式名,而不用在从图标包中导入后再使用。
参考
Tip
如果希望结合使用
sass
预编译样式,另需修改globals.css
为globals.scss
,并安装sass
依赖即可。