Next.js 中使用 UnoCSS 及其图标样式方案

前言

前端css方案有很多,从最早的bootstrap到tailwind,中间经历了各种解决方案,如scss、less、css module、style-components、emotion等。到现在风靡整个前端的tailwindcss,它们在不同的场景中具有各自的优点,我们在使用中应结合项目选择合适解决方案。

UnoCSS:一个最新的css方案,它是一个即时原子CSS引擎,设计为灵活和可扩展。在本文中我们将介绍如何在nextjs中集成UnoCSS,并使用UnoCSS icon方案替换传统的icon方案实现图标样式的极致的优化。

准备

确保已经使用create-next-app创建了一个基础应用:

bash 复制代码
pnpm dlx create-next-app@latest

根据命令行提示,选择您喜欢的配置,在本示例流程中我们选择如下:

plaintext 复制代码
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? @/*

选择Tailwind CSS是为了方便后续使用UnoCSS直接进行替换,当然也可以不选择,直接集成UnoCSS,原理都一样,操作上只是少了移除tailwindcss的流程。

开始

首先移除tailwindcss依赖

bash 复制代码
pnpm remove tailwindcss

安装UnoCSS相关依赖

bash 复制代码
pnpm add -D unocss @unocss/postcss

创建 uno.config.ts文件,并配置样式预设

ts 复制代码
// uno.config.ts
import { defineConfig, presetUno } from "unocss";

export default defineConfig({
  // ...UnoCSS options
  presets: [presetUno()],
});

globals.css 移除tainwindcss相关代码,然后导入重置浏览器默认样式行为文件,这里选择 tailwindcss 样式重置文件,同时导入unocss 样式

diff 复制代码
+ @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配置

diff 复制代码
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全部流程,现在我们来看看最终效果

bash 复制代码
pnpm dev

在浏览器中访问http://localhost:3000,发现没有,此时的页面和初始时使用tainwindcss样式一样,我们可以使用UnoCSS无缝替换tailwindcss

这里,细心的朋友会发现,我们在globals.css中删除了tailwindcss的部分代码,以及在tailwind.config.ts文件中的主题扩展还未迁移,为什么样式上没有差异呢?这是因为这两处样式本就是tailwindcss的样式预置之一,这里是为了作为示例展示给我们。当然在UnoCSS也有对应的配置方式,即在uno.config.ts文件中作如下处理:

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的替换。

这里添加了一个presetAttributify预置配置,是为了启用属性模式。这样可以更方便在代码中使用样式,并在主题配置中使用驼峰命令。
在这里您也可以作其它主题属性进行扩展,也可以定义其它的额外样式,具体请参阅UnoCSS配置

UnoCSS 图标

推荐阅读:聊聊纯 CSS 图标

一个可以使用任意的,纯CSS的,并集成于UnoCSS的图标解决方案,它遵循以下使用约定:

  • <prefix><collection>-<icon>
  • <prefix><collection>:<icon>

例如:

html 复制代码
<!-- 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包中已经包括了图标的预设,这里只需安装相应的图标库即可:

bash 复制代码
pnpm add -D @iconify-json/[the-collection-you-want]

[the-collection-you-want]Iconify图标的数据源的名称占位。例如,@iconify-json/ri对于Remix Icon、@iconify-json/heroicons对于heroicons。您可以参考IconesIconify了解所有可用的集合。

然后在uno.config.ts文件中添加图标预设

ts 复制代码
// uno.config.ts
import { defineConfig, presetIcons } from 'unocss';

export default defineConfig({
  presets: [
    presetIcons({ /* options */ }),
    // ...other presets
  ],
})

额外属性

配置图标额外属性,使其在实际样式应用中水平居中显示。

ts 复制代码
presetIcons({
  extraProperties: {
    'display': 'inline-block',
    "vertical-align": "-.125em",
    // ...
  },
})

自定义图标

在图标预设中添加自定义图标,如下配置,然后,你可以在你的 html 上使用它:<span class="i-custom:circle"></span>

ts 复制代码
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.cssglobals.scss,并安装sass依赖即可。

相关推荐
baiduopenmap2 分钟前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
请叫我欧皇i22 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
533_24 分钟前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
guokanglun30 分钟前
空间数据存储格式GeoJSON
前端
zhang-zan1 小时前
nodejs操作selenium-webdriver
前端·javascript·selenium
猫爪笔记1 小时前
前端:HTML (学习笔记)【2】
前端·笔记·学习·html
brief of gali1 小时前
记录一个奇怪的前端布局现象
前端
Json_181790144802 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
风尚云网3 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02043 小时前
前端VUE项目启动方式
前端·javascript·vue.js