はじめに
2024年にNewly availableとなったCSS関数としてround()
、mod()
、rem()
があります。これらはStepped Value Functions
と呼ばれており値を段階的に表現します。
値を段階的に調整するとは、ある値を指定された単位や基準(以後ステップ値と呼ぶ)に基づいて、その値を段階的な形式に変換するプロセスを指します。
例えば、任意の数値を指定した桁に基づいて丸め込む四捨五入は値を段階的に調整していると言えます。
round()
round()
は指定した戦略を元に段階的に調整した値を返します。
パラメータとして、丸め込みに対する戦略と対象の値、ステップ値の3つを持ちます。
丸め込みについての戦略はup
、down
、nearest
、to-zero
の4つでnearest
をデフォルト値としています。
-
up
は常にステップ数の上の倍数で丸める -
down
はステップ数の下の倍数で丸める -
nearest
は上か下の倍数で近い方の値に丸める- ちょうど真ん中の時は上の倍数に丸める
-
to-zero
はゼロに近い値の倍数へ丸める- 正の値の時は下の倍数に、負の値の時は上の倍数に丸める(上下は数直線上の概念)
対象の値やステップ値は<number>
や<dimensions>
、<percentages>
を割り当てられます。
以下が変換例です。
* {
flex-shrink: round(1.5, 1); /* 2 */
font-size: round(nearest, 1.33rem, 0.25rem); /* 1.25rem */
height: round(up, 101px, 100px); /* 200px */
width: round(down, 77%, 10%); /* 70% */
margin-right: round(to-zero, 105px, 10px); /* 100px */
margin-left: round(to-zero, -105px, 10px); /* -100px */
}
round
を利用する実用的な例として、た0.25remを
単位としたフォントサイズを提供する例を紹介します。
.any {
font-size: round(var(--unknown-font-size), 0.25rem);
}
動的なvar(--unknown-font-size)
を最も近い0.25rem
の倍数に丸めるように、整然とした文字サイズで提供します。
以下の例では--unknown-font-size
が22px
ですが、実際の値はそれに近い24px
になります(ここではChromeのデフォルトに従い1rem
を16px
の場合で考えいます。1rem
の基準に応じて調整するフォントサイズも変わります)。
See the Pen Untitled by KokiSakano (@kokisakano) on CodePen.
この他にも、デザイントークンとして一定のステップ値が定義されている値はround
を使うことで、任意の値をそれに従った値として反映できます。
mod()とrem()
mod()
とrem()
は1つ目のパラメータを2つ目のパラメータで割った余りを返します。
mod()
は2つ目のパラメータの符号を取った余りの値を、rem()
は1つ目のパラメータの符号を取った余りの値を返します。
例えば、mod(22, -3)
は余りが負になるような計算$-3\times-8-2$により$-2$を、rem(22, -3)
の場合は余りが正になるような計算$-3\times-7+1$により$1$を返します。
また、mod(-22, 3)
は余りが正になるような計算$3\times-8+2$により$2$を、rem(-22, 3)
の場合は余りが負になるような計算$3\times-7-1$により$-1$を返します。
より細かい計算が気になる場合はこちらを参照してください(JavaScriptで簡単に計算を模しただけなので、境界条件等が実際の値と異なる可能性があります)。
See the Pen Stepped Value Functions by KokiSakano (@kokisakano) on CodePen.
数式では以下のように表されます。
\begin{eqnarray}
&\mathrm{mod}(x, y) = x - \mathrm{sign}(y)\times \mathrm{round}(\mathrm{down}, x\times \mathrm{sign}(y), y) \\
&\mathrm{rem(x, y)} = x - \mathrm{round}(\mathrm{to–zero}, x, y) \\
\end{eqnarray}
$\mathrm{round}(x, y)$は最初に紹介した関数と同等のもの、$\mathrm{sign}(x)$は$x$の符号を求める関数です($\mathrm{sign}(3)=1$、$\mathrm{sign}(-55)=-1$になります)。
おわりに
CSSで値を段階的に表現するround()、mod()、rem()関数を紹介しました。
CSSで計算可能な範囲が広がることで新たな表現や、JavaScriptを用いないマークアップなどの発展を感じます。今後の動向にも期待したいです。