border・scroll-margin・overflow系ユーティリティの短縮形への自動折り畳みに対応
Tailwind CSS v4のキャノニカライズ機能が拡張され、border-t-*/border-b-*のペアがborder-y-*に、scroll-mt-*/scroll-mb-*がscroll-my-*に、overflow-x-*/overflow-y-*がoverflow-*にといった具合に、より多くのユーティリティ群が対応する短縮形に自動的に折り畳まれるようになりました。
背景
本PRは、#19837のテスト中に発見された問題を起点としています。border-x border-yがborderに折り畳まれるべきところ、折り畳まれていないことに気づいたことがきっかけです。
根本原因は expand-declaration.ts の展開マップにありました。border-widthやscroll-marginなどのショートハンドプロパティが展開対象に含まれていなかったため、キャノニカライザが「top/right/bottom/leftの4方向が揃っているか」を判断するための物理プロパティへの展開が行われていませんでした。論理プロパティ(margin-inlineなど)は既に物理プロパティへ展開される仕組みがありましたが、スクロール系の論理プロパティ(scroll-margin-blockなど)も同様に対象外でした。
PR本文が説明するように、短い論理形ショートハンド(border-xなど)に折り畳むためには、まず宣言を完全な物理形プロパティ(border-top-width、border-right-widthなど)へ展開することで、キャノニカライザが正確にシグネチャを比較できるようにする必要があります。
技術的な変更
expand-declaration.ts に新たなエントリを追加し、展開対象プロパティを拡張することが変更の核心です。これにより、キャノニカライザが物理プロパティへの展開後に正確な照合を行えるようになります。
VARIADIC_EXPANSION_MAP(値の数に応じて1〜4プロパティへ展開するマップ)に以下が追加されました:
'scroll-margin': createPrefixedQuad('scroll-margin'),
'scroll-padding': createPrefixedQuad('scroll-padding'),
'border-width': createPrefixedQuad(
'border',
'top-width',
'right-width',
'bottom-width',
'left-width',
),
'border-style': createPrefixedQuad(
'border',
'top-style',
'right-style',
'bottom-style',
'left-style',
),
'border-color': createPrefixedQuad(
'border',
'top-color',
'right-color',
'bottom-color',
'left-color',
),
gap: createPair('row-gap', 'column-gap'),
overflow: createPair('overflow-x', 'overflow-y'),
'overscroll-behavior': createPair('overscroll-behavior-x', 'overscroll-behavior-y'),
VARIADIC_LOGICAL_EXPANSION_MAP(論理プロパティを物理プロパティのペアへ展開するマップ)にはスクロール系論理プロパティが追加されました:
'scroll-margin-block': createPair('scroll-margin-top', 'scroll-margin-bottom'),
'scroll-margin-inline': createPair('scroll-margin-left', 'scroll-margin-right'),
'scroll-padding-block': createPair('scroll-padding-top', 'scroll-padding-bottom'),
'scroll-padding-inline': createPair('scroll-padding-left', 'scroll-padding-right'),
これらの展開定義が整ったことで、キャノニカライズステップでは以下の折り畳みが可能になりました:
| 入力 | 出力 |
|---|---|
border-t-123 border-r-123 border-b-123 border-l-123 |
border-123 |
border-t-1 border-r-1 border-b-1 border-l-1 |
border |
border-t-123 border-b-123 |
border-y-123 |
border-l-123 border-r-123 |
border-x-123 |
border-t-red-500 border-b-red-500 |
border-y-red-500 |
scroll-mt-123 scroll-mr-123 scroll-mb-123 scroll-ml-123 |
scroll-m-123 |
scroll-pt-123 scroll-pb-123 |
scroll-py-123 |
overflow-x-hidden overflow-y-hidden |
overflow-hidden |
overscroll-x-contain overscroll-y-contain |
overscroll-contain |
注目すべき点として、border-t-1 border-r-1 border-b-1 border-l-1がborder-1ではなくborderに折り畳まれることがあります。これはborderがborder-1と等価であり、より短い表現が優先されるためです。
設計判断
物理プロパティへの展開を「中間表現」として扱うアーキテクチャが一貫して採用されています。論理プロパティ(margin-inline)や複合ショートハンド(border-width)を直接比較するのではなく、まず全てを物理プロパティ(border-top-widthなど)へ展開してからシグネチャを照合する設計です。
PR本文にある通り、この展開によってユーティリティのシグネチャは「少し大きくなる」ものの「より正確になる」というトレードオフがあります。展開後の物理プロパティ群を比較することで、4方向・2方向の一致判定が確実に行えるようになります。またoverflowやoverscroll-behaviorのように、X/Y軸の2つが揃えば短縮形に戻せるパターンも同じ仕組みで統一的に処理されます。
createPrefixedQuadやcreatePairといった既存のファクトリ関数を再利用することで、新たなプロパティの追加は展開マップへのエントリ追加だけで完結しています。この拡張性の高さが、今後も同様のパターンで対応ユーティリティを増やしていける設計基盤になっています。
まとめ
本PRは、expand-declaration.tsの展開マップにborder-width・scroll-margin・overflow系のエントリを追加することで、キャノニカライズの対象範囲を大幅に拡大しました。「まず物理プロパティへ展開し、その後で短縮形に折り畳む」という2段階の処理を既存アーキテクチャの枠組みの中で一貫して適用することで、より多くのユーティリティ組み合わせが簡潔な表現へと自動変換されます。