> CSS・Sass > Sassでスマートに計算!知っておくべき数学関数とmathモジュール徹底解説
Sassでスマートに計算!知っておくべき数学関数とmathモジュール徹底解説

Sassでスマートに計算!知っておくべき数学関数とmathモジュール徹底解説

SassはCSSを効率的に記述するために開発されたメタ言語(拡張言語)です。
Sassについての基礎知識は下記の記事で紹介しています。

CSSでは、要素の幅、高さ、余白、フォントサイズなど様々な数値を使ってデザインを形成します。
CSSではcalc()を利用してファイル内で計算を行うことができますが、Sassではより汎用的かつ多彩な計算を行うことができます。
この記事では、Sass内での計算方法や便利な関数について紹介します。

なぜSassで計算するのか?

CSS作成時には、数値の管理や計算は避けて通れません。
通常のCSSだけでこれらの数値を管理していくと、次のような課題に直面することがよくあります。

  1. 手計算の煩雑さとヒューマンエラー

    デザインカンプから特定の要素のサイズを割り出す際にはしばしば手計算を行うことがあります。このような作業は、一つ一つは単純に見えますが、数が増えれば増えるほど時間と手間がかかり、計算ミスというヒューマンエラーのリスクも高まります。

  2. 数値変更時の手間と保守性の低下

    CSSは基本的に静的なスタイルシートなので、ある数値に変更があった場合、それに関連するすべての数値を手動で調整しなければなりません。これは開発効率を著しく低下させ、将来的な保守性を損なう原因となります。

  3. CSSファイル内のcalc()による計算はブラウザでのアクセス時に行われる

    CSSには、プロパティ値内で計算を行うための強力な関数calc()が用意されています。しかし、calc()による計算は、ブラウザがCSSをレンダリングする時点で行われますので、パフォーマンスへの影響・デバッグが複雑であるなどのデメリットもあります。

これらの課題を解決するために、Sass内で計算を行うことにより、CSSをより動的に、より効率的に、そしてより保守可能に記述できるようになります。

Sassの計算はコンパイル時に行われるため、CSSファイルには計算結果の数値が直接出力されます。
これにより、calc()のようにブラウザでの計算が発生せず、パフォーマンスの面でも優位性があります。
また、コンパイル時にエラーを検知できるため、デバッグも容易になります。

Sassでの数学処理は、デザインシステムの一貫性を保ち、将来の変更に強く、開発プロセスを高速化するための、Webフロントエンド開発における必須スキルと言えるでしょう。

Sassでの基本的な計算について

Sassは標準で、簡単な四則演算(加算・減算・乗算・除算)と剰余算をサポートしています。
ただし、単位を含んだ計算には注意が必要です。

また、除算(割り算)については後述するmathモジュールを使用した方法が推奨されています。

基本的な算術演算子(+, -, *, /, %)

Sassでは、CSSプロパティの値として、数値の計算式を直接記述することができます。
これはJavaScriptやPHPなどのプログラミング言語と似た感覚で使えます。

scss|算術演算子利用例

$container-width: 900px; // 単位は統一しておく。
$margin: 20px;           // 単位は統一しておく。

// 加算(足し算)
.content {
  width: $container-width + $margin; // 900px + 20px
}

// 減算(引き算)
.sidebar {
  width: $container-width - $margin; // 900px - 20px
}

// 乗算(掛け算)
.wide-content {
  width: $container-width * 1.5; // 900px * 1.5
}

// 除算(割り算)
.half-content {
    // 非推奨。除算に「/」は使わずmathモジュールの利用に変更すること。
    width: $container-width / 2; // 900px / 2
}

css|コンパイル結果

.content {
  width: 920px; // 900px + 20px
}

.sidebar {
  width: 880px; //  900px - 20px
}

.wide-content {
  width: 1350px; // 900px * 1.5
}

.half-content {
  width: 450px; // 900px / 2
}

※Dart Sass では、除算(割り算)で/を使うことは非推奨となっています。コンパイル時にWarningメッセージが表示されることがあります。後述するmathモジュールを利用した書き方に変更することが推奨されます。
※異なる単位が混在する計算では、コンパイル時にCompilation Errorとなる可能性があります。算術演算子で計算を行う際は、同じ単位同士の計算となるように揃えておきましょう。

剰余算(モジュロ演算) (%)

剰余算(モジュロ演算)は、割り算の余りを計算します。
ある数値が別の数値で割り切れるか、またはその際の余りがいくつになるかを知りたいときに使用します。

scss|モジュロ演算利用例

// 変数を定義
$value1: 10;
$value2: 3;
$value3: 7;
$value4: 2;

.remainder-examples {
  // 10 を 3 で割った余り (10 = 3 * 3 + 1)
  content-a: '#{$value1 % $value2}'; // 結果: 1

  // 7 を 2 で割った余り (7 = 2 * 3 + 1) -> 奇数判定
  content-b: '#{$value3 % $value4}'; // 結果: 1

  // 6 を 2 で割った余り (6 = 2 * 3 + 0) -> 偶数判定
  content-c: '#{6 % $value4}'; // 結果: 0

  // 10 を 5 で割った余り (10 = 5 * 2 + 0) -> 割り切れる
  content-d: '#{10 % 5}'; // 結果: 0
}

scss|コンパイル結果

.remainder-examples {
  content-a: '1';
  content-b: '1';
  content-c: '0';
  content-d: '0';
}

単位を含む計算と注意点

Sassで計算を行う際、CSSの単位の扱いは非常に重要です。

同じ単位同士の計算

pxpxememのように、同じ単位同士であれば問題なく計算され、結果もその単位で出力されます。

$box-width: 100px;
$padding: 20px;
.my-box {
  width: $box-width - ($padding * 2); // 結果: 60px
}

異なる単位同士の計算

pxem%vwなど、異なる単位を混ぜて計算する場合、Sassは可能な限り計算しようとしますが、コンパイル時にCompilation Errorとなる可能性があります。
または、CSSのcalc()関数として出力されることもあります。

$header-height: 60px;
$viewport-unit: 100vh;
.full-height-section {
  height: $viewport-unit - $header-height; // 結果: コンパイルエラーまたはcalc(100vh - 60px)
}

単位付きの数値と単位なしの数値との計算

単位のない数値(例: 1.5, 2)は、比率や倍率として扱われます。
これらを単位付きの数値と乗算・除算すると、単位はそのまま引き継がれます。
加算・減算の場合は、単位が揃っていないとエラーになります。

$base-size: 16px;
$ratio: 1.2;

.scaled-text {
  font-size: $base-size * $ratio; // 結果: 19.2px
}

.section{
  font-size: $base-size + 2; // エラー: 単位のない数値と単位付きの数値の加算・減算はできません
}

単位なしの数値の計算と単位の結合・連結

計算結果が単位を持たない数値(純粋な数字)になった場合でも、Sassの文字列結合機能を使えば、後から任意の単位を追加できます。
これは、複雑な計算を先に実行し、最後に適切な単位を適用したい場合に便利です。

// 変数を定義
$base-size: 8; // 単位なしの数値
$multiplier: 3;

.spacing-top {
  // #{}内で単位なしの数値同士で計算し、結果に `px` を結合
  margin-top: #{$base-size * $multiplier}px; // 結果: 24px
}

.line-height-dynamic {
  // 単位なしの数値を計算し、+演算子を使って結果に `rem` を連結
  line-height: ($base-size * 2) - 1 + "rem"; // 結果: 15rem
}

※文字列結合はインターポレーション記法(#{})や、+演算子による連結などで行えます。

Sassのmathモジュールを使いこなす

sass:mathモジュールは、四捨五入、切り上げ、切り下げ、最大値・最小値の取得、絶対値の計算といった、CSSでは直接行えない数学的な処理をSassのコンパイル時に実行できるようにします。
また、四則演算の内、除算(割り算)についてはmathモジュールの利用が推奨されています。

mathモジュールを利用することで、より複雑で動的なCSSの値を生成し、デザインシステムの一貫性を高めることが可能になります。

mathモジュールの読み込み

Sass 2.0.0以降のバージョンでは、組み込み関数を利用する際に、関連するモジュールを明示的に読み込む必要があります。
mathモジュールを使うには、スタイルシートの先頭で@use "sass:math";と記述します。

scss|mathモジュールの読み込みと利用

@use "sass:math"; // mathモジュールを読み込む

.box {
  // mathモジュール内のround関数を 'math.' という名前空間を付けて使用
  width: math.round(10.5px); // 結果: 11px
}

@useを行うことで、指定されたモジュール(ここではsass:math)をmath.という名前空間を付けて利用できるようにします。

mathモジュール利用時の注意点

mathモジュールを効果的に使うために、いくつか押さえておきたい注意点があります。

  1. モジュールを読み込み後、名前空間を利用する

    mathモジュールはスタイルシートの先頭で@use "sass:math";と記述し、モジュールを利用したい箇所ではmath.というプレフィックスを付けて呼び出して利用します。

  2. 非推奨になった古い関数は使用しない

    Sassの古いバージョン(Dart Sass 1.25.0より前、またはNode Sass)では、モジュールを読み込むことなく直接round(), ceil(), floor()などの関数を使うことができました。
    しかし、これは古い機能であり、現在は非推奨となっています。
    古い書き方で記述されたSassファイルがある場合、新しいプロジェクトでは積極的にmathモジュールを利用した書き方に移行することをおすすめします。

  3. 計算はコンパイル時に行われる

    Sassのmathモジュールで行われる計算は、すべてCSSファイルが生成されるコンパイル時に処理されます。
    これにより、最終的に出力されるCSSファイルには計算結果の数値が直接書き込まれるため、calc()関数を利用する時よりもCSSファイルが軽量化し、ブラウザは余計な計算処理を行う必要がありません。
    ブラウザの実行環境に依存する動的な計算が必要な場合は、CSSのcalc()やJavaScriptとの組み合わせを検討する必要があるので、使い分けを意識しましょう。

  4. mathモジュール利用時の単位の扱いと注意点

    Sassのmathモジュール内の関数の多くは、引数として数値を受け取ります。
    このとき、単位の有無や種類が計算結果に影響を与える可能性があるため、明示的に単位を揃えるか必要に応じて計算結果に単位を付与する必要があります。

mathモジュールを利用した基本的な計算

mathモジュールを利用した四則演算については、加算・減算・乗算は演算子で、割り算のみmath.div()を使うのが推奨されています。

除算|math.div();

2つの数値を除算します。
Sassの/演算子はCSSのショートハンドプロパティと混同されやすいという経緯があるため、明示的に除算を行う場合はmath.div()の使用が推奨されます。

scss|sass:mathモジュールを使用した除算

@use 'sass:math';

$container-width: 900; // 単位は統一しておく。
$margin: 20;           // 単位は統一しておく。

// 除算(割り算)
.half-content {
  width: math.div($container-width, 2) + px; // 900px / 2 = 450px
}

css|コンパイル結果

.half-content {
  width: 450px;
}

知っておくべきmathモジュールの主要関数

mathモジュールには、CSSの数値管理を強力にサポートする様々な関数が用意されています。
ここでは、特にWebフロントエンド開発で役立つ主要な関数を厳選してご紹介します。

数値の丸め処理

デザインにおいて、要素のサイズや余白が小数点以下の値を持つと、ブラウザでの表示にズレが生じたり、ピクセルパーフェクトなデザインを実現しにくくなることがあります。Sassのmathモジュールは、このような数値を適切に丸めるための関数を提供します。

math.round():四捨五入

最も一般的な丸め処理で、指定された数値を最も近い整数に丸めます。
小数点以下が.5以上の場合は切り上げ、.5未満の場合は切り捨てになります。

@use "sass:math";

.box-a {
  width: math.round(10.3px);  // 結果: 10px
  height: math.round(20.7em); // 結果: 21em
}

.box-b {
  padding: math.round(15.5px); // 結果: 16px (0.5は切り上げ)
}

math.ceil():切り上げ

指定された数値を、自身よりも大きいか等しい最も近い整数に切り上げます。
小数点以下がわずかでもあれば、次の整数になります。

@use "sass:math";
.item-count {
  height: math.ceil(10.1px); // 結果: 11px
}
.progress-bar {
  width: math.ceil(99.001%); // 結果: 100%
}

math.floor():切り下げ

指定された数値を、自身よりも小さいか等しい最も近い整数に切り下げます。
小数点以下がどれだけ大きくても切り捨てられます。

@use "sass:math";

.gallery-item {
  width: math.floor(100% / 3); // 結果: 33% (実際は33.333...%から切り捨て)
}

.ad-block {
  height: math.floor(50.99rem); // 結果: 50rem
}

最大値・最小値の取得

複数の候補の中から最大値や最小値を選びたい場合に役立つ関数です。
レスポンシブデザインで要素のサイズを制御したり、特定のブレークポイントでプロパティ値を調整する際によく使われます。

すべての引数の単位が同じであるか、単位なしの数値である必要があります。
異なる単位が混在するとエラーになるので注意が必要です。

math.max():複数の数値から最大値を取得

引数に渡された複数の数値の中から、最も大きい値を返します。

@use "sass:math";

// 複数の中から最大値を選ぶ
$val1: 10em;
$val2: 12em;
$val3: 8em;
.text-scale {
  font-size: math.max($val1, $val2, $val3); // 結果: 12em
}

math.min():複数の数値から最小値を取得

引数に渡された複数の数値の中から、最も小さい値を返します。

@use "sass:math";

// 複数の中から最小値を選ぶ
$val1: 100px;
$val2: 90px;
$val3: 110px;
.icon-size {
  width: math.min($val1, $val2, $val3); // 結果: 90px
}

その他の便利な関数

math.abs():絶対値の取得

指定された数値の絶対値(符号を除いた値)を返します。
距離やサイズなど、常に正の値として扱いたい場合に便利です。

@use "sass:math";

.offset-element {
  $position-offset: -20px;
  // マイナスの値でも、オフセットの「距離」として使いたい場合
  left: math.abs($position-offset); // 結果: 20px
}

.z-index-level {
  $level: -5;
  z-index: math.abs($level); // 結果: 5
}

まとめ

本記事では、Sassの数学関数やmathモジュールを紹介し、CSSの数値管理をいかに効率化するかを解説しました。
CSSのための数学処理をコンパイル時に実行することで、手計算のミスをなくし、パフォーマンスと保守性を向上できます。
これらの関数を使いこなし、よりスマートで堅牢なCSS設計を行って、コーディングのスキルアップにお役立てください。

この記事が気に入ったらシェアしてください

関連記事

Sassの繰り返し処理|@whileの使い方と実用例まとめ

Sassの繰り返し処理|@whileの使い方と実用例まとめ

Sassの繰り返し処理|@eachの使い方と実用例まとめ

Sassの繰り返し処理|@eachの使い方と実用例まとめ

Sassの繰り返し処理|@forの使い方と実用例まとめ

Sassの繰り返し処理|@forの使い方と実用例まとめ

Sassの繰り返し処理を整理しよう!@for/@each/@whileの違いと使い分けガイド

Sassの繰り返し処理を整理しよう!@for/@each/@whileの違いと使い分けガイド

Sassで配列を使おう|マップ内の値を検索する(カスタム関数の実装例)

Sassで配列を使おう|マップ内の値を検索する(カスタム関数の実装例)

Sassで配列を使おう|マップ(連想配列)を徹底的に使いこなす!

Sassで配列を使おう|マップ(連想配列)を徹底的に使いこなす!

Comment Form

コメント投稿はこちらをクリックしてください
  • コメントを入力してください。
登録フォーム
Name
Mailaddress
URL
Message
Postkey
(スパム対策に、投稿キー を半角で入力してください。)