UnoCSS动态样式进阶:响应式布局与暗黑模式深度实现

460 阅读4分钟

COVER.png

写在前面:当传统CSS遇上现代需求

"为什么我的页面在手机端显示错位?"、"用户深夜使用刺眼怎么办?"——这些前端开发高频痛点,本质上都是动态样式控制的命题。传统CSS面对响应式布局需要编写大量媒体查询,处理暗黑模式需要维护多套主题变量,而UnoCSS通过原子化思维和运行时动态生成能力,让这些需求变得像搭积木般简单。今天咱们就手把手实现这两个高频场景,看看如何用UnoCSS让样式代码既优雅又高效。


一、响应式布局的原子化革命

(1) 断点系统的本质解构

传统方案需要手动编写媒体查询:

/* 旧时代写法 */
@media (min-width: 768px) {
  .container { padding: 2rem; }
}

在UnoCSS生态中,只需通过预设的断点前缀即可实现:

<!-- 现代原子化方案 -->
<template>
  <div class="p-4 md:p-8 xl:p-12">
    <!-- 移动端4单位padding,中屏8,大屏12 -->
  </div>
</template>
/* 编译后的CSS */
.p-4 { padding: 1rem; }
@media (min-width: 768px) {
  .md\:p-8 { padding: 2rem; }
}
@media (min-width: 1280px) {
  .xl\:p-12 { padding: 3rem; }
}

技术原理:UnoCSS内置sm|md|lg|xl|2xl五级断点系统(对应640|768|1024|1280|1536px),编译时自动生成带媒体查询的样式规则。

(2) 动态类名组合技巧

结合Vue3的响应式数据实现动态布局:

// 响应式栅格系统示例
const gridColumns = ref(1) // 默认1列

watch(() => window.innerWidth, (width) => {
  gridColumns.value = width >= 1024 ? 3 : width >= 768 ? 2 : 1
})
<template>
  <div :class="`grid grid-cols-${gridColumns} gap-4`">
    <div v-for="n in 6" class="h-32 bg-blue-200 rounded-lg" />
  </div>
</template>
/* 编译后的CSS */
.grid { display: grid; }
.gap-4 { gap: 1rem; }
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.h-32 { height: 8rem; }
.bg-blue-200 { background-color: #bfdbfe; }
.rounded-lg { border-radius: 0.5rem; }

安全列表配置

// uno.config.ts
export default defineConfig({
  safelist: [
    /^grid-cols-(1|2|3)$/, // 精确匹配动态生成的类名
  ]
})

二、暗黑模式的工程化实现

(1) 基础模式切换方案

通过Vue3的组合式API管理主题状态:

// useDark.ts
import { useDark, useToggle } from '@vueuse/core'

const isDark = useDark({
  selector: 'html', // 作用在根元素
  attribute: 'theme',
  valueDark: 'dark',
  valueLight: 'light'
})
const toggleDark = useToggle(isDark)
<!-- ThemeSwitch.vue -->
<template>
  <button 
    @click="toggleDark()"
    class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700"
  >
    {{ isDark ? '🌙' : '☀️' }}
  </button>
</template>
/* 编译后的CSS */
.p-2 { padding: 0.5rem; }
.rounded-lg { border-radius: 0.5rem; }
.bg-gray-200 { background-color: #e5e7eb; }
.dark .dark\:bg-gray-700 { background-color: #374151; }

实现效果:点击按钮时自动切换<html theme="dark">属性,触发UnoCSS的暗黑模式类名。

(2) 深度定制暗黑主题

uno.config.ts中扩展自定义暗色方案:

// uno.config.ts
export default defineConfig({
  theme: {
    colors: {
      primary: {
        dark: '#5eead4', // 暗色系青绿色
        DEFAULT: '#06b6d4'
      }
    }
  },
  darkMode: 'class' // 基于CSS类名切换
})

组件中使用语义化颜色类:

<template>
  <div class="text-primary dark:text-primary-dark">
    根据主题切换的文字颜色
  </div>
</template>
/* 编译后的CSS */
.text-primary { color: #06b6d4; }
.dark .dark\:text-primary-dark { color: #5eead4; }

三、性能优化实践

(1) 按需生成验证与构建分析

通过构建分析查看输出结果:

npx unocss @src --out-file dist/uno.css

观察生成的CSS文件是否仅包含实际使用的样式规则,确保没有冗余代码。

推荐在vite配置中添加构建监听:

// vite.config.ts
export default defineConfig({
  build: {
    watch: {
      include: ['src/**/*.vue', 'src/**/*.ts']
    }
  }
})

(2) 服务端渲染(SSR)适配增强

在Nuxt3中配置SSR兼容:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@unocss/nuxt'],
  unocss: {
    preflight: true, // 注入默认样式
    ssr: true, // 启用SSR支持
    // 生产环境优化配置
    mode: 'global',
    combine: process.env.NODE_ENV === 'production'
  }
})

(3) 图层管理与样式隔离

通过图层管理实现样式优先级控制:

// uno.config.ts
export default defineConfig({
  layers: {
    components: 10,
    utilities: 20,
    mylayer: 30
  },
  shortcuts: [
    ['btn', 'layer-mylayer px-4 py-2 rounded', { layer: 'mylayer' }]
  ]
})

(4) PurgeCSS深度集成

配置PurgeCSS实现二次清理:

// uno.config.ts
export default defineConfig({
  postcss: {
    plugins: {
      '@unocss/postcss': {},
      'postcss-purgecss': {
        content: ['./src/**/*.vue'],
        safelist: [/^grid-cols-\d+$/]
      }
    }
  }
})

(5) 检查器工具使用

开发阶段启用检查器:

// vite.config.ts
export default defineConfig({
  plugins: [
    UnoCSS({
      mode: 'global',
      inspector: true // 启用浏览器检查器
    })
  ]
})

访问localhost:5173/__unocss可实时查看生成的样式规则


最后:让样式回归工程本质

通过本次分享实践可以看到,UnoCSS将响应式布局从媒体查询地狱简化为类名组合游戏,把暗黑模式从多套变量维护转化为语义化类名切换。这种原子化思维不仅提升了开发效率,更通过严格的按需生成机制保障了性能底线。
下次当你面对复杂样式需求时,不妨先思考:这个效果能否通过UnoCSS的原子类组合实现?