長さ÷長さで数値を作り、カード幅に合わせて文字の太さを変える
(100cqi - 300px) / 300px のように長さを長さで割ると単位のない数値になるので、font-weight のような「長さではない値」もコンテナ幅に連動させられる。
どんな時に使う?
- カードが広いときは見出しを太く、狭いときは細くするなど、コンテナの幅に応じて数値プロパティ(
font-weight、opacity、z-index以外の係数、scaleなど)を滑らかに変えたいとき。 - これまでは
calc()で長さ同士を割り算できなかったため、JS で幅を測るか、メディアクエリで段階的に切り替えるしかなかった。CSS の「型付き演算(typed arithmetic)」で単位同士が打ち消し合い、素の数値が得られるようになった。
コード
css
.card {
container-type: inline-size;
}
.title {
/* カード幅 300px で 300、450px で 600、600px で 900 */
font-weight: clamp(300, 300 + 600 * (100cqi - 300px) / 300px, 900);
}100cqiはコンテナのインライン方向の幅。(100cqi - 300px) / 300pxは幅 300px で 0、600px で 1 になる比率。- その比率に「変化させたい幅(600)」を掛け、「最小値(300)」を足して、
clamp()で 300〜900 に収める。 - 同じことは
progress(100cqi, 300px, 600px)でも書ける(0〜1 の比率を返す)。考え方は progress() でコンテナの幅を 0〜1 の数値にして、カードが広がるにつれキャプションをフェードインさせる を参照。
注意点・対応状況
- 中間の太さをきれいに描くには可変フォント(variable font)が必要。固定ウェイトのフォントだと近い太さに丸められて段階的に変わる。
- 長さ同士の割り算(型付き演算)は比較的新しい機能で、Chromium 系が先行している。未対応ブラウザでは宣言ごと無効になるので、前に固定値の
font-weightを書いておくと安全。 cqiを使うので、親にcontainer-type: inline-sizeが要る。