`tracking-*` ユーティリティの正規化候補選択ロジックを改善

tailwindlabs/tailwindcss

tracking-[0.05em] のような任意値クラスを名前付きユーティリティへ正規化(canonicalize)する際、複数の候補が存在しても正規形を提示できなかった問題が修正されました。負の値より正の値を優先するルールを追加することで、tracking-* 全クラスの正規化提案が機能するようになります。

背景

Tailwind CSS IntelliSense には、任意値クラス(例: tracking-[0.05em])を等価な名前付きユーティリティ(例: tracking-wider)へ置き換える提案機能があります。この正規化は内部的に「シグネチャ」を用いており、同一のシグネチャを持つ2つのクラスは同一とみなされます。

問題は、tracking-* のデフォルトテーマ値がネガティブな値を含む点にありました。たとえば tracking-tighter-0.05emtracking-wider0.05em を持ちます。このとき -tracking-tighter(元の値の符号反転)は 0.05em となり、tracking-wider と同じシグネチャを持ちます。その結果、tracking-[0.05em] の正規化候補として tracking-wider-tracking-tighter の2つが見つかり、従来の実装では「複数候補が存在する場合はスキップ」というルールにより、正規化提案が出力されませんでした。

tailwindlabs/tailwindcss-intellisense#1558 で報告されたこの問題では、以下の表のように tracking-widest だけが正しく提案される奇妙な挙動が観察されていました:

ユーティリティ名 任意値クラス 提案
tracking-tighter -0.05em tracking-[-0.05em]
tracking-tight -0.025em tracking-[-0.025em]
tracking-normal 0em tracking-[0em]
tracking-wide 0.025em tracking-[0.025em]
tracking-wider 0.05em tracking-[0.05em]
tracking-widest 0.1em tracking-[0.1em]

tracking-widest のみが提案されていたのは、-tracking-tightest が存在しないため競合候補が生じなかったという偶然の産物でした。

技術的な変更

canonicalize-candidates.ts 内の arbitraryUtilitiesbareValueUtilities の2か所において、複数候補が存在する場合のフォールバックロジックが追加されました。

変更前:

// Multiple utilities can map to the same signature. Not sure how to migrate
// this one so let's just skip it for now.
//
// TODO: Do we just migrate to the first one?
if (replacements.length > 1) return

変更後:

// Multiple utilities can map to the same signature.
if (replacements.length > 1) {
  // Prefer positive values over negative values
  let maybeReplacement: string | undefined = undefined
  for (let replacement of replacements) {
    if (replacement[0] === '-') continue // Skip negative values

    // If multiple non-negative replacements exists then we are unsure
    // what to do, so let's bail.
    if (maybeReplacement) return

    // Consider this replacement
    maybeReplacement = replacement
  }
  // ...
  return
}

新ロジックは次の手順で動作します。複数の候補が得られたとき、- で始まる候補(負値ユーティリティ)をすべてスキップし、残った非負の候補を追跡します。非負の候補が1つだけであればそれを採用し、2つ以上あれば依然として「どれを選ぶべきか不明」としてスキップします。

また、packages/tailwindcss/src/canonicalize-candidates.test.ts にはリグレッションテストが追加され、上記テーブルの全パターンと、-tracking-tightertracking-wider のような負値ユーティリティから正値への変換も検証されます。

設計判断

負の値ユーティリティの廃止ではなく、候補選択ルールの拡張 という方針が採用されました。

PR本文では -tracking-* 形式の名前付きユーティリティを deprecated にすることも検討されています。しかし公式ドキュメントの「Using negative values」でこのパターンが明示的に紹介されているため、後方互換性を壊す変更は取れませんでした。

代わりに「正の候補を負の候補より優先する」という追加ルールを設け、既存の API を変えずに問題を解消しています。このアプローチは裸値(bare value)ユーティリティに関する既存の優先度処理とも一貫しており、コードベース全体の設計方針と整合しています。

まとめ

本PRは、シグネチャベースの正規化において「複数候補がある場合は諦める」という単純なフォールバックを、「負値より正値を優先する」という明示的なルールへと昇格させた変更です。tracking-* の全ユーティリティに対して正規化提案が機能するようになり、IntelliSense の体験が改善されます。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
e9ab4575

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の構成が明確です。リード文、背景、技術詳細、設計判断、まとめがそれぞれ適切に配置されており、記事の流れが非常に分かりやすいです。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト、PR番号・Issue番号のリンク記法ともに正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

Tailwind CSSの内部実装に関するトピックであり、専門知識を持つエンジニアという対象読者に適切です。過度な説明がなく、簡潔にまとめられています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論・各論で構成され、各段落はトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られています。これにより、記事の骨子を素早く掴むことができます。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されているコードブロックは、提供されたDiff情報と完全に一致しています。ファイル名も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「正規化(canonicalize)」「シグネチャ」「任意値クラス」などの技術用語が、PRの文脈に沿って正確に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

複数候補が存在する場合の旧ロジックの問題点や、正の値を優先する新ロジックの挙動について、技術的に正確かつ論理的に説明されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(問題の原因、解決策、設計判断の経緯など)は、提供されたPRのDescriptionやDiff情報によって裏付けられており、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#19827)、Issue番号(#1558)、ユーティリティの値(-0.05emなど)はすべて正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRの内容を的確に要約しており、主題との一致性も高いです。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事はPRで言及されている情報(公式ドキュメントへのリンクなど)に限定されており、PR外の未確認な知識を持ち込んでいません。

時間表現の正確性 ⚠ WARNING

時間表現がPR情報と一致しているか

「設計判断」セクションにて、PR内での過去の検討事項を「検討されています」と現在形で表現しています。これは読者に誤解を与える可能性があります。