コハム

Webクリエイターのコハムが提供する、Web制作に役立つ情報をまとめたブログです。

知ってた?CSSでπや∞が使える!数学定数活用のすすめ

The New CSS Math: pi and other constants

記事は上記記事を意訳したものです。

※当ブログでの翻訳記事は元サイト様に許可を得て掲載しています。


CSSは数学関数(calc()など)の中で使用できる新しい数学定数を追加しました。新しい定数はpi、e、infinity、-infinity、NaNです。2024年2月現在、これらのCSS定数は最新のEdge、Chrome、Safari、Firefoxブラウザで利用可能です。

CSSのpiの基本

数学関数(calc()、pow()、round()など)の中で使用する場合、piは数学定数のπ(約3.142)と等価です。JavaScriptのMath.piと同様に、近似値を使用する代わりに定数を直接使用できます。

width: calc(pi * 3px); /* ~9.42px */
width: calc(pi * 1rad); /* ~3.14rad = 180deg */
line-height: calc(pi * .5); /* ~1.57 */

これらの数学定数は数学関数の外では使用できないことに注意が必要です。数学関数なしで使用すると、一般的な文字列として扱われます。それでもCSSとして有効な場合があります(animation-name: piのようにpiという名前のアニメーションとして使用する場合など)が、数値として使用しようとすると、ほとんどの場合は無効になります。数値のpiとして使用したい場合は、数学関数の中で使用する必要があります。

line-height: pi; /* 無効 */
animation-name: pi; /* 文字列として有効、piとして定義されたキーフレームを使用 */
animation-iteration-count: pi; /* 無効 */
animation-iteration-count: calc(pi); /* 有効、~3.14 */
animation-iteration-count: round(pi, 1); /* 有効、3 */
line-height: pow(pi, 2); /* 有効、~9.87 */

piの使用例

piを使用する利点は、数学的な精度よりも意図の明確さにあるようです。ピクセルと組み合わせて使用する場合、piは約3.1415927pxを表すと予想されます。最新のFirefox、Safari、Chrome(2024年2月時点)でgetComputedStyle()を使用すると、計算結果に若干の違いがありました。

指定されたcalc() Firefox Safari Chrome
pi * 1px 3.13333px 3.140625px 3.14062px
pi * 10px 31.4167px 31.40625px 31.4062px
pi * 100px 314.167px 314.15625px 314.156px
pi * 100000px 314159px 314159.25px 314159px

数学的な文脈でラジアンを使用することに慣れている場合、pi定数の導入によってCSSがより明確になります。以前は、CSSでラジアンを使用することはあまりありませんでした。なぜなら、ラジアンはpiを基準にしているからです。1回転は2 * piラジアンで、以前はCSSでは6.284radのような近似値で指定する必要がありました。ラジアンは、小数点の数値でしか指定できない場合、直感的ではありません。

以下は、回転の半周を定義する同等の方法です:

rotate: 180deg;
rotate: .5turn;
rotate: calc(pi * 1rad);
rotate: 3.142rad;

また、piを使用して円や曲線の長さの計算を簡略化することもできます。円の周の長さは2 * pi * radiusとして定義されるため、ストロークダッシュアニメーションの生の長さを直接CSSで計算できます。

CSSのinfinityの基本

Infinityを表す使用可能な定数が2つあり、infinityとその反対の-infinityです。どちらも実質的に、それぞれ正または負の最大可能値を表します。

z-index: calc(infinity);
z-index: pow(infinity, 1);
left: calc(-infinity * 1px);
opacity: round(down, infinity, infinity); /* 奇妙ですが、有効 */

ここでもinfinityを使用する最大の利点の1つは意図の明確さです。画面外に押し出すために可能な限り大きいピクセル値を指定したい場合、合理的な最大値と想定する任意の値を指定するよりも、infinityの方が明確(かつ安全)な選択かもしれません。

CSSのeの基本

オイラー数の数学定数を表すために、今では...eがあります!この定数は数学の対数と指数関数的成長で使用され、約2.71828に相当します。

他の定数と同じルールが適用されます:calc()のような関数の中で使用する必要があります。

opacity: calc(e / 3); /* ~.906 */
line-height: pow(e, 2); /* ~7.389; */
font-size: calc(e * 1rem); /* ~2.71828rem */
opacity: e; /* 無効 */

CSSのNaNの基本

CSSに追加された最後の数値定数は、誰もが知っている「数値ではない」を表すNaNです。CSSへのこれらのMath追加のほとんどと同様に、既存のJavaScriptのMathの概念との相関関係を可能にし、NaNも例外ではありません。仕様的には、特定の関数使用で存在しない値の表現を可能にします。例えば、ゼロでの剰余を求める(rem(3, 0)など)と、ゼロによる除算は数学的に不可能なためNaNとなります。これを仕様で提供することで、JavaScriptのNaNのバージョンにマッピングし、CSS計算が明確な方法で数値に結果を出さない状況を表現する方法を提供します。

しかし実際には、CSSは何らかの値に解決する必要があります。NaNを直接値として使用するか、それに解決する計算で使用するかにかかわらず、計算された値を確認すると、最終的に有効な値が適用されていることがわかります。

例えば、以下の特定のCSSを持つ要素の場合:

#element {
  opacity: 1;
  opacity: calc(NaN);
}

Firefox、Safari、Chromeのそれぞれで、2番目のopacity宣言は有効な値として適用されます。この場合、適用される計算値は0です。同様に、2番目のopacityがopacity: rem(9, 0)として定義されていた場合(仕様では2番目のパラメータがゼロの場合、常にNaNに解決すると述べています)、rem(9, 0)とcalc(NaN)は事実上同じNaNであるため、計算値は依然として0です。

width: calc(NaN * 1px)を試みると、計算値は0pxになります。z-index: calc(NaN)も0です...z-index: calc(NaN * infinity)も同様です。

ただし、これはもう問題を引き起こしているだけです。

©コハム