【Sass】数値から単位を除去する方法|strip-unitとunitlessの誤解

Sassで計算や比較をするとき、10px のような単位付きの数値から単位を取り除いて純粋な数値(10)にしたいことがあります。ここでよくある誤解が「unitless() を使えば単位が外れる」というものですが、これは間違いです。unitless() は単位を除去するのではなく、単位が付いているかどうかを判定する関数です。この記事では、正しい単位の外し方を解説します。

この記事の結論:単位の除去は math.div($value, ($value * 0 + 1)) で行います。単位が分かっているなら math.div(10px, 1px) でもOKです。unitless()(現在は math.is-unitless())は単位の有無を返す判定用で、除去はできません。
スポンサーリンク

よくある誤解:unitless()では単位は外れない

unitless()真偽値(true / false)を返す関数です。引数に単位がなければ true、あれば false を返すだけで、数値そのものは変わりません。

NG: unitlessは判定関数(除去できない)
@use "sass:math";

// 単位が「付いているか」を返すだけ
.a { content: "#{math.is-unitless(10px)}"; } // false
.a { content: "#{math.is-unitless(10)}";   } // true

// ↓ これは誤り。false が代入され、計算でエラーになる
// $n: unitless(10px); // = false(10 ではない!)
// width: $n * 2;      // false * 2 でエラー
グローバルの unitless() は非推奨です。判定したい場合は @use "sass:math"; を読み込んでmath.is-unitless() を使ってください。いずれにせよ、これらは「判定」であって「除去」ではありません。

正しい単位の除去:strip-unit関数

Sassには「単位だけを外す」専用の関数はありません。定番は、同じ単位の 1 で割る方法です。$value * 0 + 1 で「値と同じ単位の1」を作り、それで割ると単位が打ち消されます。汎用の strip-unit() 関数にしておくと便利です。

strip-unit関数(どんな単位でも除去)
@use "sass:math";

@function strip-unit($value) {
  @if math.is-unitless($value) {
    @return $value;
  }
  @return math.div($value, ($value * 0 + 1));
}

.a { width: strip-unit(10px);  }  // 10
.b { width: strip-unit(2.5rem); } // 2.5
.c { width: strip-unit(42);     } // 42(もともと単位なし)

外したい単位が分かっている場合は、その単位の 1 で割るだけでも除去できます。

単位が分かっている場合
@use "sass:math";

.a { width: math.div(10px, 1px); }   // 10
.b { width: math.div(2rem, 1rem); }  // 2

なぜ単位を外すのか

単位を外したくなる典型は次のような場面です。

  • 計算の途中で純粋な数値が必要なとき(比率の算出など)
  • 異なる単位を混ぜたくないとき(pxrem など)
  • 数値だけを別の単位に付け替えたいとき
数値だけ取り出して別単位を付ける
@use "sass:math";

@function strip-unit($value) {
  @if math.is-unitless($value) { @return $value; }
  @return math.div($value, ($value * 0 + 1));
}

$base: 16px;
// px の数値だけ取り出して計算し、単位を付け直す
.text { font-size: strip-unit($base) * 1.5 + 0px; } // 24px
単位の付け替えで代表的なpx→remの変換はpxからremへ変換する方法で詳しく解説しています。丸め処理はround()で四捨五入切り上げ・切り捨てを参照してください。

よくある質問(FAQ)

Qunitless()で単位を外せないのですか?
A外せません。unitless()(現在は math.is-unitless())は単位が付いているかを真偽値で返す判定関数です。単位の除去には math.div($value, ($value * 0 + 1)) を使います。
Qstrip-unitの「$value * 0 + 1」は何をしているのですか?
A値と同じ単位を持つ「1」を作っています10px * 0 + 11px になり、それで 10px を割ると単位が打ち消されて 10 になります。
Q単位が分かっている場合の簡単な方法はありますか?
Aその単位の 1 で割るだけです。math.div(10px, 1px)10 になります。汎用的に使うなら本文の strip-unit() 関数が便利です。
Q単位なしの数値をstrip-unitに渡しても大丈夫ですか?
A大丈夫です。本文の strip-unit()math.is-unitless() で先に判定し、単位がなければそのまま返すようにしているため、エラーになりません。

まとめ

Sassで単位を除去するポイントを整理します。

  • unitless()math.is-unitless())は判定関数で、除去はできない
  • 除去は math.div($value, ($value * 0 + 1))
  • 単位が分かっているなら math.div(10px, 1px) でもよい
  • 汎用の strip-unit() 関数を用意すると便利
  • グローバル unitless() は非推奨 → math.is-unitless()

関連として、pxからremへ変換する方法round()で四捨五入数値の絶対値を取得もあわせて読むと、Sassの数値処理に強くなれます。