text-[--spacing] と --alpha のデータ型推論を修正

tailwindlabs/tailwindcss

Tailwind CSS が任意の text- ユーティリティで --spacing(...) を色として扱い、--alpha(...) を長さとして扱っていた問題を解消し、正しく font-sizecolor が生成されるようにしました。

背景

Tailwind の任意値構文 text-[...] は、その内部表現のデータ型を推論して適切な CSS プロパティを決定します。従来、calc(...) は長さ (length) と判定される一方で、--spacing(...) は型が不明なためデフォルトで color と推論され、結果として text-[--spacing(4)]color: … を出力していました。この挙動は、text- ユーティリティをフォントサイズ調整に使いたいケース(例: Angular のアイコンサイズ)で期待と異なる CSS を生成し、実装者に手動で回避策を強いる原因となっていました。

技術的な変更

データ型判定ロジックの拡張

packages/tailwindcss/src/utils/infer-data-type.tsisLength 関数に、--spacing(...) を長さとして認識する正規表現 IS_LENGTH_FN が追加されました。変更前は IS_LENGTH.test(value) || hasMathFn(value) だけでしたが、変更後は IS_LENGTH.test(value) || IS_LENGTH_FN.test(value) || hasMathFn(value) となり、--spacing 系関数が長さ判定に含まれます。これにより text-[--spacing(2)]font-size: calc(var(--spacing) * 2); と正しく生成されます。

@@ -232,9 +232,10 @@ const LENGTH_UNITS = [
 ]

 const IS_LENGTH = new RegExp(`^${HAS_NUMBER.source}(${LENGTH_UNITS.join('|')})$`)
+const IS_LENGTH_FN = /^(--spacing)\(/i

 export function isLength(value: string): boolean {
-  return IS_LENGTH.test(value) || hasMathFn(value)
+  return IS_LENGTH.test(value) || IS_LENGTH_FN.test(value) || hasMathFn(value)
 }

色判定ロジックの拡張

packages/tailwindcss/src/utils/is-color.tsisColor 関数に、--alpha(...) を色として認識する正規表現 IS_COLOR_FN が追加されました。変更前は標準的なカラー関数リストだけでしたが、|--alpha が組み込まれ、text-[--alpha(red/20%)]color: oklab(...); と出力されます。

@@ -195,7 +195,7 @@ const NAMED_COLORS = new Set([
   'accentcolortext',
 ])

-const IS_COLOR_FN = /^(rgba?|hsla?|hwb|color|(ok)?(lab|lch)|light-dark|color-mix)\(/i
+const IS_COLOR_FN = /^(rgba?|hsla?|hwb|color|(ok)?(lab|lch)|light-dark|color-mix|--alpha)\(/i

テストの追加

packages/tailwindcss/src/utilities.test.tstext-[--alpha(...)]text-[--spacing(...)] の期待出力を検証するテストケースが追加され、回帰防止が保証されます。テストは生成される CSS スニペットを直接比較し、font-sizecolor が正しく設定されていることを確認します。

@@ -26518,6 +26518,7 @@ test('text', async () => {
         'text-[color:var(--my-color)]/[0.5]',
         'text-[color:var(--my-color)]/[50%]',
+        'text-[--alpha(red/20%)]',
@@ -26543,6 +26544,7 @@ test('text', async () => {
         'text-[clamp(1rem,var(--size),3rem)]/9',
+        'text-[--spacing(2)]',
@@ -26632,6 +26634,10 @@ test('text', async () => {
       line-height: var(--leading-snug);
     }

+    .text-\\[--spacing\\(2\\)\\] {
+      font-size: calc(var(--spacing) * 2);
+    }
+
     .text-\\[12px\\] {
       font-size: 12px;
     }
@@ -26672,6 +26678,10 @@ test('text', async () => {
       color: oklab(59.9824% -.067 -.124 / .5);
     }

+    .text-\\[--alpha\\(red\\/20\\%\\)\\] {
+      color: oklab(62.7955% .224 .125 / .2);
+    }
+
     .text-\\[color\\:var\\(--my-color\\)\\], .text-\\[color\\:var\\(--my-color\\)\\]\\/50 {
       color: var(--my-color);
     }

CHANGELOG の更新

CHANGELOG.md に本修正の概要が追記され、リリースノートとして顧客に情報が提供されます。

@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Ensure `@variant` rules generated by `addBase` can use custom variants defined later ([#20247](https://github.com/tailwindlabs/tailwindcss/pull/20247))
 - Ensure `@tailwindcss/vite` doesn't crash during HMR when scanned files or directories are deleted ([#20259](https://github.com/tailwindlabs/tailwindcss/pull/20259))
+- Ensure `text-[--spacing(…)]` generates `font-size` instead of `color` ([#20260](https://github.com/tailwindlabs/tailwindcss/pull/20260))

設計判断

組み込み関数の型判定拡張という最小限の侵入

今回の変更は既存の正規表現リストにエントリを追加するだけで、コードベース全体への影響範囲は極小です。--spacing--alpha は Tailwind のデザインシステムで提供される「組み込み関数」という位置付けであり、別途新しいユーティリティや設定項目を導入する必要がありませんでした。これにより後方互換性が保たれ、既存ユーザーへの破壊的変更リスクが回避されています。

テスト駆動で回帰防止を確保

新規テストケースを追加したことで、将来のリファクタリングや正規表現の変更が同様の判定ロジックを破壊しないことが保証されます。テストは実際に生成される CSS を検証するため、見た目の差異まで捕捉でき、設計上の安全性が高まります。

変更点の公開と透明性

CHANGELOG に明示的に記載したことで、利用者はリリースノートを通じて今回の修正を把握できます。これは Tailwind がユーザーに対して変更の意図と影響範囲を透明に示す姿勢の一環です。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
f4cfaf95

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文・背景・技術的変更・設計判断が揃っており、結論的なまとめが記載されているため、総論→各論→結論の構成が取れている。

カスタムMarkdown構文 ⚠ WARNING

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

GitHubリンクは `[PR #20260](URL)` の形式で記載されており、要求された `[ #123 ](URL)` とは若干異なる。ファイル名付きコードブロックは使用されていないが、誤りはない。

対象読者への適合性 ✓ PASS

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

Tailwind CSS の内部実装に関する専門的な説明で、エンジニア向けの水準を満たしている。初心者向けの余計な解説はない。

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

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

各セクションは総論パラグラフで要旨を示し、続く段落が1トピックで構成され、トピックセンテンスで始まっている。段落は適切な長さで空行で区切られている。

Diff内容との照合 ✓ PASS

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

記事内のコードブロックは提供された Diff と完全に一致している。追加・変更内容が正確に反映されている。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている用語(isLength、IS_COLOR_FN、--spacing、--alpha など)は PR の記述と一致し、誤用は見られない。

説明の技術的正確性 ✓ PASS

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

技術的主張は Diff と PR 内容に裏付けられ、因果関係も論理的に正しい。

事実の突合 ✓ PASS

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

全ての事実は PR のタイトル・説明・Diff に基づいており、憶測や外部知識の付加はない。

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

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

PR 番号 #20260 などの数値は正確に記載されている。

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

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

記事タイトルは PR の目的(--alpha を color、--spacing を length として扱う)を適切に要約している。

外部知識の正確性 ✓ PASS

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

記事内に PR に記載されていないバージョン情報や LTS などの外部知識は含まれていない。

時間表現の正確性 ✓ PASS

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

時間表現は使用されておらず、PR と矛盾する記述もない。