テック技報最新号へ →
CSS

progress() でコンテナの幅を 0〜1 の数値にして、カードが広がるにつれキャプションをフェードインさせる

progress(100cqi, 300px, 500px) は「コンテナ幅が 300px のとき 0、500px のとき 1」になる数値を返すので、opacity などに直接入れるとメディアクエリの段階切り替えなしに連続的に変化させられる。

@sanyampunia · 2026-10-20
#progress#コンテナクエリ#cqi#レスポンシブ#フェード

どんな時に使う?

  • カードが狭いときは補足のキャプションを隠し、広くなるにつれて少しずつ見せたい時
  • @container (min-width: …) でパッと切り替えるのではなく、幅に応じてなめらかに見た目を変えたい時
  • 透明度だけでなく、拡大率・ぼかし・余白なども「幅に比例して」変えたい時

コード

css
.card {
  container-type: inline-size; /* カード自身をサイズコンテナにする */
}

.caption {
  /* コンテナ幅 300px で 0、400px で 0.5、500px で 1 */
  opacity: progress(100cqi, 300px, 500px);
}
  • progress(値, 始点, 終点) は「値が始点〜終点のどこにいるか」を 0〜1 の数値で返す CSS の数学関数。始点より小さければ 0、終点より大きければ 1 に張り付く(範囲外にはみ出さない)。
  • 100cqi は「一番近いサイズコンテナのインライン方向の幅の 100%」。container-type: inline-size を付けた .card の幅がそのまま入る。
  • 返り値は単位のない数値なので、opacity にはそのまま、長さに使うときは calc() で単位を掛ける。
css
.caption {
  --p: progress(100cqi, 300px, 500px);
  opacity: var(--p);
  translate: 0 calc((1 - var(--p)) * 8px); /* 広がるほど下から定位置へ */
  filter: blur(calc((1 - var(--p)) * 4px));
}

注意点・対応状況

  • progress() は比較的新しい関数で、Chrome / Edge は 138 以降で使える。Firefox・Safari の対応状況は導入前に caniuse などで確認し、未対応ブラウザ向けに opacity: 1; を先に書いておくと「常に表示」に落ちる。
  • cqi などのコンテナクエリ単位は、祖先に container-type を持つ要素が無いとビューポート基準(小さい方の svi 相当)として計算されてしまう。コンテナ指定を忘れないこと。
  • 透明度 0 のキャプションも、スクリーンリーダーには読まれ、クリックも受ける。完全に隠したい幅では @container で visibility: hidden を併用する。
  • 元の投稿は動画のデモ付き。上の2つ目のコード(translate や blur の併用)は応用例として組み立てたもの。

出典

X の元の投稿を開く