LoginSignup
1
0

More than 3 years have passed since last update.

JavaScriptでコントラストのアクセシビリティ適合レベルを求める

Posted at

アクセシビリティの記事やツールで良く見かける『AA』や『AAA』を自分で求める方法です。

color_a11y.gif

TL;DR

一応クラス使ってそれっぽく書いてみました。

a11y.js
class PartOfRGB {
    constructor (param) {
        this.param = param
    }

    // 16進数
    toHex () {
        return this.param.toString(16)
    }

    // 8bitをsRGBに変換する
    toSRGB () {
        return this.param / 255
    }

    // 相対輝度計算に使うためのRGB
    getRGBForRelativeLuminance () {
        const sRGB = this.toSRGB()

        if (sRGB <= 0.03928){
            return sRGB / 12.92;
        }

        return Math.pow(((sRGB + 0.055) / 1.055), 2.4);
    }
}

class RGB {
    constructor (strRGB) {
        const rgb = this.convStrToRGB(strRGB)
        this.R = new PartOfRGB(rgb[0])
        this.G = new PartOfRGB(rgb[1])
        this.B = new PartOfRGB(rgb[2])
    }

    // 16進数の文字列
    toStr () {
        return `#${this.R.toHex()}${this.G.toHex()}${this.B.toHex()}`
    }

    // #fffff → [255, 255, 255]
    convStrToRGB (strRGB) {
        return strRGB.match(/[^#]{2}/g).map(rgb => parseInt(rgb, 16))
    }

    // 相対輝度
    getRelativeLuminance () {
        const R = this.R.getRGBForRelativeLuminance();
        const G = this.G.getRGBForRelativeLuminance();
        const B = this.B.getRGBForRelativeLuminance();
        return 0.2126 * R + 0.7152 * G + 0.0722 * B;
    }
}

class ColorContrast {
    constructor (strC1, strC2) {
        this.c1 = new RGB(strC1)
        this.c2 = new RGB(strC2)
    }

    // コントラスト比
    getContrastRatio () {
        const l1 = this.c1.getRelativeLuminance()
        const l2 = this.c2.getRelativeLuminance()
        const bright = Math.max(l1, l2)
        const dark = Math.min(l1, l2)
        return Math.round((bright + 0.05) / (dark + 0.05) * 100) / 100
    }

    // コントラスト比がアクセシブルかを判定する
    judgeA11y () {
        const contrastRatio = this.getContrastRatio()

        if (contrastRatio >= 7) {
            return 'AAA'
        } else if (contrastRatio >= 4.5) {
            return 'AA'
        }
        return 'NG'
    }
}

const CC1 = new ColorContrast('#FFE6E6', '#ffffff')
const CC2 = new ColorContrast('#c7a999', '#1d1616')

console.log(`${CC1.c1.toStr()}, ${CC1.c2.toStr()}`)
console.log(`コントラスト比: ${CC1.getContrastRatio()}`)
console.log(`アクセシビリティ: ${CC1.judgeA11y()}`)
console.log()
console.log(`${CC2.c1.toStr()}, ${CC2.c2.toStr()}`)
console.log(`コントラスト比: ${CC2.getContrastRatio()}`)
console.log(`アクセシビリティ: ${CC2.judgeA11y()}`)

出力

出力
#ffe6e6, #ffffff
コントラスト比: 1.19
アクセシビリティ: NG

#c7a999, #1d1616
コントラスト比: 8.11
アクセシビリティ: AAA

簡単な説明

  1. 2つの色それぞれの相対輝度を求める
  2. 2つの色のコントラスト比を求める
  3. コントラスト比によって適合レベルを判別する
    1. コントラスト比 >= 7.0 : AAA
    2. コントラスト比 >= 4.5 : AA

相対輝度を求める過程がちょっと複雑ですが、それ以外は分かりやすいと思います。

応用

これを応用して、3色のアクセシビリティをチェックするツールをReactで作ってみました。
https://a11y-contrast-tool.vercel.app/

参考

https://waic.jp/docs/WCAG20/Overview.html
W3C勧告のWCAG公式ドキュメントです。

https://lifehackdev.com/ZakkiBlog/articles/detail/web15
コードはここを参考にしました。

https://ja.wikipedia.org/wiki/Help:%E9%85%8D%E8%89%B2%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%88%E3%83%A9%E3%82%B9%E3%83%88%E6%AF%94
Wikipediaのa11yヘルプです。かなり分かりやすくまとまっています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0