Skip to main content
Technology & EngineeringCss Styling Services227 lines

UnoCSS

"UnoCSS: instant on-demand atomic CSS engine, presets, shortcuts, rules, variants, attributify mode, icon support, inspector"

Quick Summary23 lines
You are an expert in styling applications with UnoCSS, the instant on-demand atomic CSS engine.

## Key Points

- Use `presetUno` as a solid default and add other presets (icons, typography, attributify) as needed rather than loading everything.
- Prefer shortcuts for repeated utility combinations instead of duplicating long class strings across components.
- Use the UnoCSS Inspector (`http://localhost:5173/__unocss`) during development to visualize generated CSS and debug matching issues.
- Forgetting to import `virtual:uno.css` in the entry point results in no styles being applied, with no error message.
- Dynamic class strings constructed at runtime (e.g., `` `bg-${color}-500` ``) will not be detected by UnoCSS because it uses static string scanning. Use safelist or explicit class names instead.

## Quick Example

```bash
npm install -D unocss
```

```ts
// main.ts
import 'virtual:uno.css'
import '@unocss/reset/tailwind.css' // optional CSS reset
```
skilldb get css-styling-services-skills/UnoCSSFull skill: 227 lines
Paste into your CLAUDE.md or agent config

UnoCSS — CSS & Styling

You are an expert in styling applications with UnoCSS, the instant on-demand atomic CSS engine.

Core Philosophy

Overview

UnoCSS is a highly extensible, performant atomic CSS engine that generates utility CSS on demand. Unlike traditional frameworks that ship a fixed set of utilities, UnoCSS is fully customizable via presets, rules, and shortcuts. It supports Tailwind-like utilities, Windi CSS syntax, Attributify mode, pure CSS icons, and more — all through its preset system. It has zero dependencies on a core level and achieves instant performance by skipping parsing and AST — it works purely via string matching.

Setup & Configuration

Installation (Vite)

npm install -D unocss

Vite Configuration

// vite.config.ts
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    UnoCSS(),
  ],
})

UnoCSS Configuration

// uno.config.ts
import {
  defineConfig,
  presetUno,
  presetAttributify,
  presetIcons,
  presetTypography,
} from 'unocss'

export default defineConfig({
  presets: [
    presetUno(),           // Tailwind / Windi CSS compatible utilities
    presetAttributify(),   // Attributify mode
    presetIcons({          // Pure CSS icons
      scale: 1.2,
      cdn: 'https://esm.sh/',
    }),
    presetTypography(),    // Prose / typography support
  ],
  shortcuts: {
    'btn': 'px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600 transition-colors',
    'card': 'p-4 rounded-xl shadow-md bg-white dark:bg-gray-800',
  },
  rules: [
    // Custom rules: [matcher, styles]
    ['custom-gradient', { background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }],
    // Dynamic rules with regex
    [/^m-(\d+)px$/, ([, d]) => ({ margin: `${d}px` })],
  ],
  theme: {
    colors: {
      brand: {
        DEFAULT: '#3b82f6',
        dark: '#1d4ed8',
      },
    },
    breakpoints: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
    },
  },
})

Entry Point

// main.ts
import 'virtual:uno.css'
import '@unocss/reset/tailwind.css' // optional CSS reset

Core Patterns

Utility Classes (presetUno)

UnoCSS with presetUno supports Tailwind-compatible utilities out of the box:

<div class="flex items-center gap-4 p-6 bg-white rounded-xl shadow-lg">
  <img class="w-12 h-12 rounded-full" src="/avatar.png" alt="avatar" />
  <div>
    <h2 class="text-lg font-semibold text-gray-900">Username</h2>
    <p class="text-sm text-gray-500">Description</p>
  </div>
</div>

Attributify Mode

Attributify mode lets you group utilities by category as HTML attributes:

<button
  bg="blue-500 hover:blue-600 dark:blue-400"
  text="white sm"
  p="x-4 y-2"
  border="~ rounded-lg"
  transition="colors"
>
  Click Me
</button>

Pure CSS Icons (presetIcons)

<!-- Use any Iconify icon set as pure CSS -->
<div class="i-carbon-sun text-2xl text-yellow-500" />
<div class="i-mdi-github text-3xl" />
<div class="i-logos-vue" />

Shortcuts (Reusable Compositions)

// uno.config.ts
export default defineConfig({
  shortcuts: [
    // Static shortcut
    { 'btn-primary': 'bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600' },
    // Dynamic shortcut with regex
    [/^btn-(.*)$/, ([, c]) => `bg-${c}-500 text-white px-4 py-2 rounded hover:bg-${c}-600`],
  ],
})
<button class="btn-primary">Submit</button>
<button class="btn-green">Confirm</button>
<button class="btn-red">Delete</button>

Variants and Responsive Design

<div class="
  grid grid-cols-1
  sm:grid-cols-2
  lg:grid-cols-3
  gap-4
  dark:bg-gray-900
  print:hidden
">
  <div class="hover:scale-105 transition-transform">Card</div>
</div>

Variant Groups

UnoCSS supports variant groups to reduce repetition:

<!-- Instead of: hover:bg-blue-500 hover:text-white hover:shadow-lg -->
<button class="hover:(bg-blue-500 text-white shadow-lg)">
  Hover Me
</button>

<div class="dark:(bg-gray-800 text-white border-gray-700)">
  Dark mode content
</div>

Custom Rules

// uno.config.ts
export default defineConfig({
  rules: [
    // Static rule
    ['scrollbar-hide', { 'scrollbar-width': 'none', '-ms-overflow-style': 'none' }],

    // Dynamic rule
    [/^text-ellipsis-(\d+)$/, ([, lines]) => ({
      display: '-webkit-box',
      '-webkit-line-clamp': lines,
      '-webkit-box-orient': 'vertical',
      overflow: 'hidden',
    })],
  ],
})

Best Practices

  • Use presetUno as a solid default and add other presets (icons, typography, attributify) as needed rather than loading everything.
  • Prefer shortcuts for repeated utility combinations instead of duplicating long class strings across components.
  • Use the UnoCSS Inspector (http://localhost:5173/__unocss) during development to visualize generated CSS and debug matching issues.

Common Pitfalls

  • Forgetting to import virtual:uno.css in the entry point results in no styles being applied, with no error message.
  • Dynamic class strings constructed at runtime (e.g., `bg-${color}-500`) will not be detected by UnoCSS because it uses static string scanning. Use safelist or explicit class names instead.

Anti-Patterns

Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.

Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.

Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.

Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.

Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.

Install this skill directly: skilldb add css-styling-services-skills

Get CLI access →