Sassでコントラスト比を計算しWCAGの達成基準かどうかチェックする

Sassでコントラスト比を計算し、WCAGの達成基準かどうかをチェックする Mixin を作りました。


Dart Sass 1.79.3 以上で動作します。



```scss
@use 'sass:math';
@use 'sass:color';

// 相対輝度を計算する関数
@function calculate-luminance($color) {
  $r: math.div(color.channel($color, "red", $space: rgb), 255);
  $g: math.div(color.channel($color, "green", $space: rgb), 255);
  $b: math.div(color.channel($color, "blue", $space: rgb), 255);
  // 計算方法の参考： https://www.w3.org/TR/WCAG22/#dfn-relative-luminance
  $r: if($r < 0.04045, math.div($r, 12.92), math.pow(math.div(($r + 0.055), 1.055), 2.4));
  $g: if($g < 0.04045, math.div($g, 12.92), math.pow(math.div(($g + 0.055), 1.055), 2.4));
  $b: if($b < 0.04045, math.div($b, 12.92), math.pow(math.div(($b + 0.055), 1.055), 2.4));
  @return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
}

// コントラスト比を計算する関数
@function contrast-ratio($color1, $color2) {
  $l1: calculate-luminance($color1);
  $l2: calculate-luminance($color2);
  @if $l1 > $l2 {
    // 計算方法の参考： https://www.w3.org/TR/WCAG22/#dfn-contrast-ratio
    @return floor-to-2decimals(math.div(($l1 + 0.05), ($l2 + 0.05)));
  } @else {
    @return floor-to-2decimals(math.div(($l2 + 0.05), ($l1 + 0.05)));
  }
}

// コントラスト比がWCAGの達成基準を満たしているかチェックする関数
@function success-criterion($contrast) {
    @if $contrast >= 7 { @return "AAA"; }
    @else if $contrast >= 4.5 { @return "AA";}
    @else if $contrast >= 3 { @return "AA (Large Text)"; }
    @else { @return "Fail"; }
}

// 小数点以下2桁で切り下げる関数
@function floor-to-2decimals($number) {
  $factor: 100;
  @return math.div(math.floor($number * $factor), $factor);
}

// Mixinにまとめる
@mixin check-contrast($foreground, $background) {
  $contrast-ratio: contrast-ratio($foreground, $background);
  $accessibility: success-criterion($contrast-ratio);
  @debug 'コントラスト比:#{$contrast-ratio} #{$accessibility}';
}
```


## 使い方
@include で呼び出します。引数に比較するカラーコードを入れます。
```scss
// 呼び出し
@include check-contrast(#ffffff, #bf4080); // 出力結果「コントラスト比:4.92 AA」
```


`@debug` でコントラスト比と達成基準が出力されます。

![ScreenShot 2024-12-04 at 17.55.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16548/db13ee33-ba17-4062-18de-77bd5dc2750b.png)


## DEMO


[Sass:Playground](https://sass-lang.com/playground/#eJylVF1L21AYvu+vONSCzdavxHZu6SYtg+1muxnCrpP0JAbTRE4Su1EEkw4UdehEHZvbZIOpY6CCDLQT/8wxqV7tL+zkq2u7GhkrgZ7z5n2fvO/zPOfQdMXUIRjVOV1n65wxNVpO9EQETdEQCSXyedDZPnEOzy/PPjrtXWyvX+4vdg7eYusdtpevtr64m0eJimiqgiFrKhA4RTAVzoBZxazLKqcKMJ3ywSjQTACQQizwvparybNpP54TpjhVhUqYlgFJBGvJDEjpM5wAWYAknsoAplSiyl69dHO9hCBUr0fgb0bgFRNeC0AYCShwt07d401sHTir9uV869fZezBlGDM6m883Go1cYyynISk/+Sz//GH1McPkR2qimkWQsCPP9vATsiKL6RQC90EhVygWiqXMnyZTpCWayd1jqDA4ozXS3bde1W2virRH8sJ/JlekuoR50NJwaCkeWoqF5gNofjg0Hw/Nx0FXEDRMpJIEhmbugFsgHHKcLjHeLuxrnPF3fDkx5zsV28e4RZ5F3PqG7VOycA83brSsphqI040sIsJooQloor6/YELfKjQbY246IERh4pKYYDRZ9NDAhJfuY/+vpfoH8AEj/kRF01DW0LJMDQpynVP0XglIF4EGhPq01024CzSYAxWokAuh+S+ITB8iPYAYK5O14g1FZr+yNtzFNWen7ba3iHhuex5bO9gi+u1i6xWREFvLuGVhew+3Wtg+vEZX3RQEqOtZAckGRCTiyRAwRUVDeVpEQTDxAIyDZnfSZLVaTZZJ036mT8VgejFX6i9IluPSx/qTQfoJhyQIJuELgxr4Uk/iI05W/LcBec7RKpmzY59e/Px6cbLMuJ8tbO05iwvYXiJ7bK0PI2OIbCnVrPMwupdFTjA0cg3RhULvAexq6y98lKjQO3lBFRE7WkUn8an8Qlax9R1b59jaxzZRazlRqXtRIExBYbrr2nRK1BCUkGaqNYLDc8J0sAkb63c3+9dxva7aP5CcbwGZlxXZeMnGWSKAC05oDfKmBEaH2pQdaQ7UzAES6vvQ3GhEg/PmDFvHzkKb2DdRkVVBMWtwkIAR0f9lwAgvFgt3C1TZuxBIkbO03fmx5n76gOdXhjdTJPcrqFbx/OvfUePXbQ==?s=L1C1-L50C68) に DEMO を置いています。




## 告知

2024年12月11日に発売予定の [Web制作者のためのSassの教科書 改訂3版](https://book3.scss.jp/) に掲載しています。