ルール

UnoCSS のカスタムルール作成はとても簡単です。

ルール

ルールはユーティリティクラスと結果として生成される CSS を定義します。UnoCSS には多くの組み込みルールがありますが、カスタムルールを簡単に追加することもできます。

静的ルール

この例では:

rules: [
  ['m-1', { margin: '0.25rem' }],
]

ユーザーのコードベースで m-1 が検出されると、次の CSS が生成されます:

.m-1 {
  margin: 0.25rem;
}

注意: 本体の構文は CSS プロパティの構文に従います。例:fontWeight ではなく font-weight。プロパティ名にハイフン - が含まれる場合は引用符で囲む必要があります。

rules: [
  ['font-bold', { 'font-weight': 700 }],
]

動的ルール

よりスマートにするために、マッチャーを RegExp に変更し、本体を関数にします:

rules: [
  [/^m-(\d+)$/, ([, d]) => ({ margin: `${d / 4}rem` })],
  // `theme` や `symbols` などの豊富なコンテキスト情報を第二引数から取得できます。
  [/^p-(\d+)$/, (match, ctx) => ({ padding: `${match[1] / 4}rem` })],
]

本体関数の第一引数は、マッチしたグループを取得するために分解できる RegExp のマッチ結果です。

例えば、次の使用例では:

<div class="m-100">
  <button class="m-3">
    <icon class="p-5" />
    My Button
  </button>
</div>

対応する CSS が生成されます:

.m-100 { margin: 25rem; }
.m-3 { margin: 0.75rem; }
.p-5 { padding: 1.25rem; }

おめでとうございます!これで強力なアトミック CSS ユーティリティを手に入れました。楽しんでください!

CSS ルールのフォールバック

新しい CSS 機能を使用しつつ、古いブラウザをサポートするために CSS ルールのフォールバックを活用したい場合、同じキーでルールの CSS 表現として 2D 配列を返すことができます。例えば:

rules: [
  [/^h-(\d+)dvh$/, ([_, d]) => {
    return [
      ['height', `${d}vh`],
      ['height', `${d}dvh`],
    ]
  }],
]

これにより h-100dvh は次のように生成されます:

.h-100dvh { height: 100vh; height: 100dvh; }

特殊シンボル

バージョン 0.61 以降、UnoCSS は生成された CSS に追加のメタ情報を定義するための特殊シンボルをサポートしています。@unocss/core から symbols オブジェクト、または動的ルールマッチャー関数の第二引数からシンボルにアクセスできます。

例えば:

::: code-group

静的ルール
import { symbols } from '@unocss/core'

rules: [
  ['grid', {
    [symbols.parent]: '@supports (display: grid)',
    display: 'grid',
  }],
]
動的ルール
rules: [
  [/^grid$/, ([, d], { symbols }) => {
    return {
      [symbols.parent]: '@supports (display: grid)',
      display: 'grid',
    }
  }],
]

:::

次のように生成されます:

@supports (display: grid) {
  .grid {
    display: grid;
  }
}

:::tip ルールがどのように生成されるかを正確に知っている場合、UnoCSS のパフォーマンスを向上させるために 静的ルール を使用することをお勧めします。 :::

利用可能なシンボル

シンボル説明
symbols.parent生成された CSS ルールの親ラッパー(例:@supports@media など)
symbols.selector生成された CSS ルールのセレクタを修正するための関数(以下の例を参照)
symbols.layer生成された CSS ルールの UnoCSS レイヤーを設定(文字列、関数、または正規表現マッチが可能)
symbols.variants現在の CSS オブジェクトに適用されるバリアントハンドラの配列
symbols.shortcutsNoMerge現在のルールのショートカットでのマージを無効にするためのブール値
symbols.noMerge現在のルールのマージを無効にするためのブール値
symbols.sort現在の CSS オブジェクトのソート順序を上書きするための数値
symbols.body生成された CSS ルールの本体を完全に制御(#4889 を参照)

マルチセレクタルール

バージョン 0.61 以降、UnoCSS は JavaScript Generator 関数 を介してマルチセレクタをサポートします。そして、単一 のルールから 複数 の CSS ルールを生成します。

例えば:

::: code-group

静的ルール
rules: [
  ['button-red', [
    { background: 'red' },
    {
      [symbols.selector]: selector => `${selector}:hover`,
      // https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix
      background: `color-mix(in srgb, red 90%, black)`
    },
  ]],
]
動的ルール
rules: [
  [/^button-(.*)$/, function* ([, color], { symbols }) {
    yield {
      background: color
    }
    yield {
      [symbols.selector]: selector => `${selector}:hover`,
      // https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix
      background: `color-mix(in srgb, ${color} 90%, black)`
    }
  }],
]

:::

複数の CSS ルールが生成されます:

.button-red {
  background: red;
}
.button-red:hover {
  background: color-mix(in srgb, red 90%, black);
}

完全に制御されたルール

::: tip これは高度な機能であり、ほとんどの状況では必要ありません。 :::

動的ルールバリアントの組み合わせでカバーされない高度なルールが本当に必要な場合、UnoCSS は CSS を生成するための完全な制御を提供する方法もあります。

動的ルールの本体関数から文字列を返すことができ、これは生成された CSS に直接渡されます(これにより、CSS のエスケープ、バリアントの適用、CSS の構築などを自分で処理する必要があります)。

uno.config.ts
import { defineConfig, toEscapedSelector as e } from 'unocss'

export default defineConfig({
  rules: [
    [/^custom-(.+)$/, ([, name], { rawSelector, currentSelector, variantHandlers, theme }) => {
      // マッチしないルールを破棄
      if (name.includes('something'))
        return

      // このルールのバリアントを無効にしたい場合
      if (variantHandlers.length)
        return
      const selector = e(rawSelector)
      // オブジェクトではなく文字列を返す
      return `
${selector} {
  font-size: ${theme.fontSize.sm};
}
/* 複数のルールを持つことができます */
${selector}::after {
  content: 'after';
}
.foo > ${selector} {
  color: red;
}
/* またはメディアクエリ */
@media (min-width: ${theme.breakpoints.sm}) {
  ${selector} {
    font-size: ${theme.fontSize.sm};
  }
}
`
    }],
  ],
})

::: warning 上記の方法は生成された CSS を完全に制御できますが、variants を通じて拡張することはできず、バリアントによってもたらされる柔軟性を失います。

例:hover:custom-xxx -> hover バリアントは機能しません。 :::

したがって、出力を完全にカスタマイズしつつ、バリアントの利便性を享受したい場合は、symbols.body を使用してこれを実現することを検討できます。

::: code-group

静的ルール
import { symbols } from '@unocss/core'

rules: [
  ['custom-red', {
    // symbols.body はスタイルを囲む `{}` を必要としません
    [symbols.body]: `
      font-size: 1rem;
      &::after {
        content: 'after';
      }
      & > .bar {
        color: red;
      }
    `,
    [symbols.selector]: selector => `:is(${selector})`,
  }]
]
動的ルール
rules: [
  [/^custom-(.+)$/, ([_, c], { symbols }) => {
    return {
      [symbols.body]: `
        font-size: 1rem;
        &::after {
          content: 'after';
        }
        & > .bar {
          color: ${c};
        }
      `,
      [symbols.selector]: selector => `:is(${selector})`,
    }
  }]
]

:::

hover:custom-red から完全な CSS ルールが生成されます:

:is(.hover\:custom-red):hover {
  font-size: 1rem;
  &::after {
    content: 'after';
  }
  & > .bar {
    color: red;
  }
}

順序

UnoCSS は生成された CSS において定義されたルールの順序を尊重します。後のものほど優先度が高くなります。

動的ルールを使用する場合、複数のトークンにマッチすることがあります。デフォルトでは、単一の動的ルールの下でマッチしたものの出力は、グループ内でアルファベット順にソートされます。

ルールのマージ

デフォルトで、UnoCSS は CSS のサイズを最小化するために同じ本体を持つ CSS ルールをマージします。

例えば、<div className="m-2 hover:m2"> は次のように生成されます:

.hover\:m2:hover,
.m-2 {
  margin: 0.5rem;
}

2つの別々のルールではなく:

.hover\:m2:hover {
  margin: 0.5rem;
}
.m-2 {
  margin: 0.5rem;
}