組み込みサイズを使用して計算する

ウェブ機能: calc-size() interpolate-size

calc-size() は、auto、min-content、fit-content などの固有のサイズ設定キーワードに対して数学演算を実行するための CSS 関数です。必須: calc-size() は、計算または制約を使用して固有のサイズを変更する必要がある場合にのみ使用します。単純なキーワードベースのアニメーション(0 から auto など)には、interpolate-size: allow-keywords を使用する必要があります。

実装の手順

  1. 組み込みの基底を特定する: 計算の基底となる組み込みキーワード(auto、min-content など)を決定します。
  2. 制約を定義する: 2 番目の引数内で clamp()、min()、max() などの CSS 数学関数を使用して、固有サイズにデザイン制約を適用します。
  3. 必須: 代替を指定する。calc-size() を使用するプロパティの直前に、標準のサイズ指定キーワードまたは長さを常に宣言して、サポートされていないブラウザでもレイアウトが機能するようにします。
  4. 論理プロパティを適用する: デフォルトでは、inline-size や block-size などの論理プロパティを使用して、ドキュメントの書き込みモードを考慮して計算が行われます。
  5. 省略可: プログレッシブ エンハンスメント: 複雑なレイアウト ロジックやアニメーションを @supports (inline-size: calc-size(auto, size + 0px)) ブロックでラップして、対応しているブラウザにのみ高度な機能を提供します。

基本的な構文

/* calc-size(<calc-size-basis>, <calc-sum>) — mathematical operations on intrinsic sizing keywords */
.element {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: min-content;
  
  /* DO: Use calc-size to modify an intrinsic basis with a calculation or function */
  inline-size: calc-size(min-content, size + 2rem);
}

有効な基準引数(<calc-size-basis>)

最初の引数は、計算の「基本」サイズを定義します。

標準キーワード:

  • auto: 要素のデフォルトのサイズ。
  • min-content: 要素がオーバーフローせずに取ることができる最小サイズ。
  • max-content: すべてのコンテンツを 1 行に収めるために要素が取るサイズ。
  • fit-content: clamp(min-content, auto, max-content) と同等。
  • content: calc-size() が flex-basis プロパティ内で使用されている場合にのみ有効です。

特別な引数:

  • any: 特定の組み込み型が不明な場合や、計算をネストする場合に使用される汎用的な基底。
  • ネストされた calc-size(): 複数ステップの計算や条件付き計算が可能です。
  • <calc-sum>: 特定の長さ、割合、または数式(例: 100px、20%)。固定値を基準として使用する場合、size キーワードは引き続き使用できます(ただし、2 番目の引数内のみ)。これは、その基準の解決された値を表します。

必須: size キーワードは、最初の引数(<calc-size-basis>)内では無効です。これは、2 番目の引数(<calc-sum>)内から基底を参照するためにのみ存在するローカル変数です。

有効な計算引数(<calc-sum>)

2 番目の引数は数式です。

  • 通常、size キーワードを使用して、基底の値を参照します。
  • size キーワードは技術的には省略可能ですが、省略すると、計算は固定値に解決され、基準は完全に無視されます。
  • 標準の数学演算子(+、-、*、/)を含めることができます。
  • clamp()、min()、max()、round() などの CSS 数学関数を含めることができます。
  • 必須: calc-size() では、各計算で 1 つの固有サイズ値(基準)のみを使用できます。同じ calc-size() 呼び出しで、固有のサイズ設定キーワードを混在させることはできません。

ユースケース

組み込みサイズとの間のアニメーション

デフォルトでは、ブラウザは長さ(0px など)と固有のキーワード(auto など)の間を補間できません。キーワードを calc-size() でラップすると、補間可能な値になります。

アニメーションに適したツールの選択

  • 必須: interpolate-size: allow-keywords を使用する: 数学的な変更を伴わない、固有サイズへの、または固有サイズからの単純なアニメーション(height: 0 から height: auto など)。これは、単純なキーワード補間に必要なアプローチであり、理想的には :root を介してグローバルに適用する必要があります。

    :root {
      /* Best practice: Enable keyword interpolation globally */
      interpolate-size: allow-keywords;
    }
    
    .item {
      height: 0;
      transition: height 0.3s ease;
    }
    
    .item.open {
      /* Simple interpolation from 0 to auto now works without calc-size() */
      height: auto;
    }
    
  • calc-size() を使用する: 遷移中に固有サイズに対して数学的な計算を行う必要がある場合(パディングの追加やサイズのクランプなど)にのみ使用します。

.accordion-content {
  display: block;
  overflow: hidden;
  /* MANDATORY: Fallback value for closed state */
  block-size: 0;
  transition: block-size 0.3s ease-out;
}

.accordion-content.open {
  /* MANDATORY: Fallback value for open state */
  block-size: auto;

  /* 
    DO: Use calc-size(auto, ...) to enable animation from 0 to the element's 
    intrinsic size while doing a calculation (in this case, adding a space of 2rem).
  */
  block-size: calc-size(auto, size + 2rem);
}

必須: 2 つの固有サイズ設定キーワード間の補間は直接行うことはできません。トランジションの片端は、長さまたはパーセンテージにする必要があります。

ユーザーのモーション設定を尊重する

大きなレイアウト領域のサイズを変更するアニメーションは、前庭障害のあるユーザーにとって特に不快なものになる可能性があります。必須: prefers-reduced-motion メディアクエリを使用して、必須ではないアニメーションを簡素化または最小化することで、ユーザーのモーション設定を常に尊重します。一般的な戦略としては、モーションを完全に無効にする、時間を短縮する、レイアウト シフトを不透明度の微妙な遷移に置き換えるなどがあります。

.accordion-content {
  opacity: 0;
  transition: block-size 0.3s ease, opacity 0.3s ease;
}

.accordion-content.open {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .accordion-content {
    /* 
       EXAMPLE: Replacing disruptive layout animations with a subtle fade-in.
       Setting the block-size instantly and transitioning opacity 
       provides a clear state change without large-scale motion.
    */
    transition: opacity 1.5s ease;
  }

  .accordion-content.open {
    /* Jump the size instantly */
    block-size: auto;
  }
}

固有サイズに制約を適用する

calc-size() を min()、max()、clamp()、round() などの CSS 数学関数と組み合わせて使用すると、要素の固有サイズがデザインの境界内に収まるようにできます。

.dynamic-container {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: fit-content;

  /* 
    DO: Establish a dynamic size based on content, while:
    1. Enforcing boundaries using CSS math functions (min, clamp, etc.)
    2. Modifying the intrinsic size with fixed or relative offsets
  */
  inline-size: calc-size(fit-content, min(size + var(--extra-space), var(--max-allowed)));
}

重要な考慮事項

  • パーセンテージの落とし穴: <calc-sum> 内のパーセンテージは、size キーワードではなく、コンテナのサイズに対して解決されます。たとえば、calc-size(auto, size + 10%) を指定すると、親の幅の 10% が要素の auto 幅に追加されるため、予期しない結果やオーバーフローが発生する可能性があります。
  • 計算の要件: 必須: 単純なアニメーション(0 から auto など)には、calc-size() ではなく interpolate-size: allow-keywords を使用します。calc-size() は、レイアウトで固有のベースに動的な数学的調整が必要な場合にのみ使用してください。
  • パフォーマンスに関する注記: inline-size や block-size などのボックスモデル プロパティをアニメーション化すると、レイアウトの再計算がトリガーされ、負荷が高くなる可能性があります。calc-size() アニメーションは、主にレイアウトに不可欠な要素で、レイアウト以外の代替手段では不十分な場合に使用します。

代替戦略

calc-size() と interpolate-size はプログレッシブ エンハンスメントです。これらのプロパティをサポートしていないブラウザでは、プロパティは無視され、レイアウトは引き続き機能します。ただし、固有のキーワードへのアニメーションは、遷移ではなくジャンプします。フォールバックとして、標準のキーワードまたは長さを必ず指定してください。

.element {
  /* Fallback for browsers that don't support calc-size() */
  inline-size: fit-content; 
  /* Modern browsers will override the fallback */
  inline-size: calc-size(fit-content, size + 2rem);
}

アニメーションと遷移のフォールバック

calc-size() または interpolate-size をサポートしていないブラウザでは、固有サイズ設定キーワードを含む遷移は補間されません。

  • グレースフル デグラデーション: デフォルトのフォールバックは、状態間の「インスタント ジャンプ」(0 から auto など)です。レイアウトは機能し続けるため、多くの場合、これは許容されます。
  • エクスペリエンスの向上: @supports を使用して、複雑なレイアウト ロジックや、スムーズな組み込みアニメーションが可能な場合にのみ意味を持つ追加のスタイルを適用します。
  • JS ベースの測定を避ける: JavaScript を使用して要素を測定し、そのサイズを手動でアニメーション化することもできますが、これは多くの場合不要であり、レイアウト スラッシングにつながる可能性があります。ネイティブの「インスタント ジャンプ」に依存することは、最新のウェブ アプリケーションに推奨されるフォールバックです。

アニメーションの場合、代替表示では最終サイズに瞬時にジャンプします。CSS または JavaScript でサポートを検出するには:

/* CSS Feature Detection */
@supports (inline-size: calc-size(auto, size + 0px)) {
  .element {
    /* Apply advanced logic only when supported */
  }
}
/* JavaScript Feature Detection */
if (CSS.supports('inline-size', 'calc-size(auto, size + 0px)')) {
  // Apply advanced sizing or animations
}