見出し画像

CSSのmin()やmax()関数がSassでIncompatible unitsエラーになる

ここ数年の CSS の進化は目覚ましく、それにより新たな問題が起きるようになりました。Sass には与えられた引数のうち最小値を返す min() 関数と与えられた引数のうち最大値を返す max() 関数があります。

しかし、CSS にも標準で min() 関数と max() 関数が実装されたことにより、関数名の衝突が起きてしまいます。

色々なエラー

とはいっても、普通に使う分には問題ありません。

.selector {
  width: min(1px, 2px);
}

これを Sass でコンパイルすると、

.selector {
  width: 1px;
}

となります。しかし、Sass では解釈できないような vw や vh 単位を使うとエラーが起きます。

.selector {
  width: min(1px, 1vw);
}

コンパイルすると、Incompatible units: 'vw' and 'px'. というエラーが表示されます。コンパイル時点では 1vw の値が確定していないため、静的解釈できないからです。

.selector {
  width: min(calc(1px + 2px), 1px);
}

また、min() 関数内で calc() 関数を使うと、Error: "calc(1px + 2px)" is not a number for min エラーが表示されます。

これは、Sass の min() 関数の引数には数値を指定しなければなりませんが、calc() という不明な値が指定されているためです。

.selector {
  --number: 2px;
  width: min(var(--number), 1px);
}

もちろん、CSS 変数を使うこともできません。​

エラーが起きる関数​

CSS の関数名と Sass の関数名が同じためにエラーが起きるものを一覧にしました。

・min()
・max()
・rgb()
・rgba()
・hsl()
・hsla()
・invert()
・grayscale()
・opacity()

rgb() 関数や rgba() 関数でも CSS 変数との併用でエラーが起きるため、結構困ります。

解決策

unquote() 関数は引用符を取り除いてくれるものですが、そのまま出力したいときに使えます。

.selector {
  width: unquote('min(1px, 1vw)');
}

引数に文字列として指定することで、そのまま出力できます。

// Sassのmin()関数
@function _min($numbers...) {
  @return min($numbers...);
}
// CSSのmin()関数
@function min($values...) {
  @return unquote('min(#{$values})');
}

また、Sass の関数を再定義することで、エラーを回避させることもできます。Sass の min() 関数は _min() 関数として定義しておいて、min() 関数は unquote() 関数でそのまま出力させるようにしています。

Sass の新モジュールシステムでは名前空間があるため、math.min() や math.max() というように名前の衝突は起きません。しかし、rgb() や rgba()、hsl()、hsla() はグローバル関数として定義されているため、依然としてエラーが起きます。

なぜ、color.rgb() みたいに color 名前空間に属していないのかという疑問が残りますが。

今すぐ始めるCSSレシピブック

この記事が気に入ったらサポートをしてみませんか?