html 生成一对符合对比度需求的对比色 及对颜色间的对比度探究
侧边栏壁纸
  • 累计撰写 12 篇文章
  • 累计收到 7 条评论
    已存活 146231316

html 生成一对符合对比度需求的对比色 及对颜色间的对比度探究

jacksen168
2023-01-07 / 0 评论 / 11 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年01月07日,已超过446天没有更新,若内容或图片失效,请留言反馈。

前言

往往前端工程师在选择文本颜色和背景色上一直很头疼,选择的颜色和背景色比例过小的话就会出现看文字眼花的情况,如:
html 生成一对符合对比度需求的对比色 及对颜色间的对比度探究-1.png

适合阅读的 色彩对比度比例不小于 4.5:1
适合老年人阅读的 不小于7:1
这里分享一个网站: 色彩对比度检查器 (点击跳转)

html 生成一对符合对比度需求的对比色 及对颜色间的对比度探究-2.png
html 生成一对符合对比度需求的对比色 及对颜色间的对比度探究-3.png

下面给大家分享能够生成一对自定义颜色对比度的方法

随机生成一对能自定义颜色对比比例的颜色 javascript代码

//颜色生成
function Generate_contrast_color(strength, min_contrast, max_contrast) {
    // 随机一个16位颜色
    function getRandomColor() {
        let color = Math.floor((Math.random() * 256 * 256 * 256)).toString(16)
        while (color.length < 6) {//随机生成的可能只有3-6位字符串
            color += Math.floor((Math.random() * 16)).toString(16)
        }
        return '#' + color;
    }

    //16进制转RGB
    function colorToRGB(type, color) {
        let color1, color2, color3;
        color = '' + color;
        if (typeof color !== 'string') return;
        if (color.charAt(0) == '#') {
            color = color.substring(1);
        }
        if (color.length == 3) {
            color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
        }
        if (/^[0-9a-fA-F]{6}$/.test(color)) {
            color1 = parseInt(color.substr(0, 2), 16);
            color2 = parseInt(color.substr(2, 2), 16);
            color3 = parseInt(color.substr(4, 2), 16);
            if (type == 1) {
                return `rgb(${color1},${color2},${color3})`;
            } else {
                return [color1, color2, color3];
            }
        }
    };

    //判断颜色灰度 核心原理:颜色于白色进行对比
    //color 颜色 ,数据类型16位哈希颜色 或 rgb值的数组:[255,255,255]
    function islight(color) {
        function luminance(r, g, b) {
            var a = [r, g, b].map(function (v) {
                v /= 255;
                return v <= 0.03928
                    ? v / 12.92
                    : Math.pow((v + 0.055) / 1.055, 2.4);
            });
            return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
        }
        function contrast(color) {//返回值范围 1 ~ 21
            if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color)) {
                rgb = colorToRGB(2, color);
            } else {
                rgb = color;
            }
            var lum1 = luminance(255, 255, 255);
            var lum2 = luminance(rgb[0], rgb[1], rgb[2]);
            var brightest = Math.max(lum1, lum2);
            var darkest = Math.min(lum1, lum2);
            return (brightest + 0.05)
                / (darkest + 0.05);
        }
        if (contrast(color) < 11) {//值小于11表示鲜艳,大于11表示暗淡
            //颜色鲜艳
            return true
        } else {
            //颜色暗淡
            return false
        }
    };

    // 生成对比色
    function lightColor(sColor, iStep) {
        var asHex = new Array(16);
        var haxString = '0123456789abcdef';
        for (var i = 0; i < 16; i++) {
            asHex[i] = haxString.substr(i, 1);
        }

        var sRslt = "#";
        var iTemp;
        for (var i = 1; i < 7; i++) {
            iTemp = parseInt("0x" + sColor.substr(i, 1)) + iStep;
            if (iTemp > 15)
                iTemp = 15;
            if (iTemp < 0)
                iTemp = 0;
            sRslt += asHex[iTemp];
        }
        return sRslt;
    }

    //将颜色按照暗亮自动前往对比
    function autolightColor(color, istep) {
        if (!islight(color)) {
            //暗色
            return lightColor(color, istep);
        } else {
            //亮色
            return lightColor(color, -istep)
        }
    }

    //计算两色的对比度比例
    //colorA 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
    //colorB 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
    function getContrastRatio(colorA, colorB) {
        if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorA)) {
            colorA = colorToRGB(2, colorA);
        }
        if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorB)) {
            colorB = colorToRGB(2, colorB);
        }

        function getLuminanace(values) {
            var rgb = values.map((v) => {
                var val = v / 255;
                return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
            });
            return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
        };

        var lumA = getLuminanace(colorA);
        var lumB = getLuminanace(colorB);

        var calculation = (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);

        return calculation.toFixed(2);
    };

    //随机一对
    let i = 0;
    do {//不是任意一对颜色都是有合适的对比率的,又时初始颜色偏激,但范围有限会导致对出来的颜色对比度不合格
        i++;
        var color = getRandomColor();
        var ContrastColor = autolightColor(color, strength);
        var ContrastRatio = getContrastRatio(color, ContrastColor);
        if (min_contrast < ContrastRatio && ContrastRatio < max_contrast) {
            return [color, ContrastColor, ContrastRatio]
        }
    } while (i < 10000)//阀门
    console.log('经循环10000次,没有合适的一对,返回白色和黑色');
    return ['#fff', '#000', 21]

}
//Generate_contrast_color(strength, min_contrast, max_contrast)
//strength = 两色偏移强度; 范围0 ~ 20 ;必须整数
//min_contrast = 最小对比度比例; 范围1 ~ 21
//max_contrast = 最大对比度比例; 范围1 ~ 21
/*--最后生成的颜色对比度比例在 最小对比度比例 和 最大对比度比例 之间。错误返回白色和黑色--*/

/*
返回值:
["#b0b6ce","#404057","5.01"]
[ 颜色1 , 颜色2 , 两色对比比例 ]
*/

var color = Generate_contrast_color(7, 4.5, 21);
var color1 = color[0];
var color2 = color[1];
var ContrastRatio = color[2];

其余便是分支:

如果需要将16位颜色转换成rgb可以这样:

//16进制转RGB
function colorToRGB(color) {
    let color1, color2, color3;
    color = '' + color;
    if (typeof color !== 'string') return;
    if (color.charAt(0) == '#') {
        color = color.substring(1);
    }
    if (color.length == 3) {
        color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
    }
    if (/^[0-9a-fA-F]{6}$/.test(color)) {
        color1 = parseInt(color.substr(0, 2), 16);
        color2 = parseInt(color.substr(2, 2), 16);
        color3 = parseInt(color.substr(4, 2), 16);
        return `rgb(${color1},${color2},${color3})`;
    }
};

颜色偏移:

//颜色偏移
//sColor 16位哈希颜色 如:#99cf42
//iStep 偏移力度 0 ~ 20
function lightColor(sColor, iStep) {
    var asHex = new Array(16);
    var haxString = '0123456789abcdef';
    for (var i = 0; i < 16; i++) {
        asHex[i] = haxString.substr(i, 1);
    }

    var sRslt = "#";
    var iTemp;
    for (var i = 1; i < 7; i++) {
        iTemp = parseInt("0x" + sColor.substr(i, 1)) + iStep;
        if (iTemp > 15)
            iTemp = 15;
        if (iTemp < 0)
            iTemp = 0;
        sRslt += asHex[iTemp];
    }
    return sRslt;
}

计算两个颜色的对比度比例:

//16进制转RGB
function colorToRGB(type, color) {
    let color1, color2, color3;
    color = '' + color;
    if (typeof color !== 'string') return;
    if (color.charAt(0) == '#') {
        color = color.substring(1);
    }
    if (color.length == 3) {
        color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
    }
    if (/^[0-9a-fA-F]{6}$/.test(color)) {
        color1 = parseInt(color.substr(0, 2), 16);
        color2 = parseInt(color.substr(2, 2), 16);
        color3 = parseInt(color.substr(4, 2), 16);
        if (type == 1) {
            return `rgb(${color1},${color2},${color3})`;
        } else {
            return [color1, color2, color3];
        }
    }
};

//计算两色的对比度比例
//colorA 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
//colorB 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
function getContrastRatio(colorA, colorB) {
    if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorA)) {
        colorA = colorToRGB(2, colorA);
    }
    if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorB)) {
        colorB = colorToRGB(2, colorB);
    }

    function getLuminanace(values) {
        var rgb = values.map((v) => {
            var val = v / 255;
            return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
        });
        return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
    };

    var lumA = getLuminanace(colorA);
    var lumB = getLuminanace(colorB);

    var calculation = (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);

    return calculation.toFixed(2);
};

判断颜色是否鲜艳

//16进制转RGB
function colorToRGB(type, color) {
    let color1, color2, color3;
    color = '' + color;
    if (typeof color !== 'string') return;
    if (color.charAt(0) == '#') {
        color = color.substring(1);
    }
    if (color.length == 3) {
        color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
    }
    if (/^[0-9a-fA-F]{6}$/.test(color)) {
        color1 = parseInt(color.substr(0, 2), 16);
        color2 = parseInt(color.substr(2, 2), 16);
        color3 = parseInt(color.substr(4, 2), 16);
        if (type == 1) {
            return `rgb(${color1},${color2},${color3})`;
        } else {
            return [color1, color2, color3];
        }
    }
};

//判断颜色灰度 核心原理:颜色于白色进行对比
//color 颜色 ,数据类型16位哈希颜色 或 rgb值的数组:[255,255,255]
function islight(color) {
    function luminance(r, g, b) {
        var a = [r, g, b].map(function (v) {
            v /= 255;
            return v <= 0.03928
                ? v / 12.92
                : Math.pow((v + 0.055) / 1.055, 2.4);
        });
        return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
    }
    function contrast(color) {//返回值范围 1 ~ 21
        if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color)) {
            rgb = colorToRGB(2, color);
        } else {
            rgb = color;
        }
        var lum1 = luminance(255, 255, 255);
        var lum2 = luminance(rgb[0], rgb[1], rgb[2]);
        var brightest = Math.max(lum1, lum2);
        var darkest = Math.min(lum1, lum2);
        return (brightest + 0.05)
            / (darkest + 0.05);
    }
    if (contrast(color) < 11) {//值小于11表示鲜艳,大于11表示暗淡
        //颜色鲜艳
        return true
    } else {
        //颜色暗淡
        return false
    }
};

html演示:

<!DOCTYPE html>
<html lang="zh_cn">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>随机一对合适的颜色,对比度比例可控,演示随机100个</title>
</head>

<body>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <script>
        //颜色生成
        function Generate_contrast_color(strength, min_contrast, max_contrast) {
            // 随机一个16位颜色
            function getRandomColor() {
                let color = Math.floor((Math.random() * 256 * 256 * 256)).toString(16)
                while (color.length < 6) {//随机生成的可能只有3-6位字符串
                    color += Math.floor((Math.random() * 16)).toString(16)
                }
                return '#' + color;
            }

            //16进制转RGB
            function colorToRGB(type, color) {
                let color1, color2, color3;
                color = '' + color;
                if (typeof color !== 'string') return;
                if (color.charAt(0) == '#') {
                    color = color.substring(1);
                }
                if (color.length == 3) {
                    color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
                }
                if (/^[0-9a-fA-F]{6}$/.test(color)) {
                    color1 = parseInt(color.substr(0, 2), 16);
                    color2 = parseInt(color.substr(2, 2), 16);
                    color3 = parseInt(color.substr(4, 2), 16);
                    if (type == 1) {
                        return `rgb(${color1},${color2},${color3})`;
                    } else {
                        return [color1, color2, color3];
                    }
                }
            };

            //判断颜色灰度 核心原理:颜色于白色进行对比
            //color 颜色 ,数据类型16位哈希颜色 或 rgb值的数组:[255,255,255]
            function islight(color) {
                function luminance(r, g, b) {
                    var a = [r, g, b].map(function (v) {
                        v /= 255;
                        return v <= 0.03928
                            ? v / 12.92
                            : Math.pow((v + 0.055) / 1.055, 2.4);
                    });
                    return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
                }
                function contrast(color) {//返回值范围 1 ~ 21
                    if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color)) {
                        rgb = colorToRGB(2, color);
                    } else {
                        rgb = color;
                    }
                    var lum1 = luminance(255, 255, 255);
                    var lum2 = luminance(rgb[0], rgb[1], rgb[2]);
                    var brightest = Math.max(lum1, lum2);
                    var darkest = Math.min(lum1, lum2);
                    return (brightest + 0.05)
                        / (darkest + 0.05);
                }
                if (contrast(color) < 11) {//值小于11表示鲜艳,大于11表示暗淡
                    //颜色鲜艳
                    return true
                } else {
                    //颜色暗淡
                    return false
                }
            };

            // 生成对比色
            function lightColor(sColor, iStep) {
                var asHex = new Array(16);
                var haxString = '0123456789abcdef';
                for (var i = 0; i < 16; i++) {
                    asHex[i] = haxString.substr(i, 1);
                }

                var sRslt = "#";
                var iTemp;
                for (var i = 1; i < 7; i++) {
                    iTemp = parseInt("0x" + sColor.substr(i, 1)) + iStep;
                    if (iTemp > 15)
                        iTemp = 15;
                    if (iTemp < 0)
                        iTemp = 0;
                    sRslt += asHex[iTemp];
                }
                return sRslt;
            }

            //将颜色按照暗亮自动前往对比
            function autolightColor(color, istep) {
                if (!islight(color)) {
                    //暗色
                    return lightColor(color, istep);
                } else {
                    //亮色
                    return lightColor(color, -istep)
                }
            }

            //计算两色的对比度比例
            //colorA 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
            //colorB 颜色1 输入16位哈希 或 rgb值的数组:[255,255,255]
            function getContrastRatio(colorA, colorB) {
                if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorA)) {
                    colorA = colorToRGB(2, colorA);
                }
                if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(colorB)) {
                    colorB = colorToRGB(2, colorB);
                }

                function getLuminanace(values) {
                    var rgb = values.map((v) => {
                        var val = v / 255;
                        return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
                    });
                    return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
                };

                var lumA = getLuminanace(colorA);
                var lumB = getLuminanace(colorB);

                var calculation = (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);

                return calculation.toFixed(2);
            };

            //随机一对
            let i = 0;
            do {//不是任意一对颜色都是有合适的对比率的,又时初始颜色偏激,但范围有限会导致对出来的颜色对比度不合格
                i++;
                var color = getRandomColor();
                var ContrastColor = autolightColor(color, strength);
                var ContrastRatio = getContrastRatio(color, ContrastColor);
                if (min_contrast < ContrastRatio && ContrastRatio < max_contrast) {
                    return [color, ContrastColor, ContrastRatio]
                }
            } while (i < 10000)//阀门
            console.log('经循环10000次,没有合适的一对,返回白色和黑色');
            return ['#fff', '#000', 21]

        }
        //Generate_contrast_color(strength, min_contrast, max_contrast)
        //strength = 两色偏移强度; 范围0 ~ 20 ;必须整数
        //min_contrast = 最小对比度比例; 范围1 ~ 21
        //max_contrast = 最大对比度比例; 范围1 ~ 21
        /*--最后生成的颜色对比度比例在 最小对比度比例 和 最大对比度比例 之间。错误返回白色和黑色--*/

        /*
        返回值:
        ["#b0b6ce","#404057","5.01"]
        [ 颜色1 , 颜色2 , 两色对比比例 ]
        */

        var color = Generate_contrast_color(7, 4.5, 21);
        var color1 = color[0];
        var color2 = color[1];
        var ContrastRatio = color[2];

        /*----------------------下面为演示代码---------------------*/

        function setStyle(el, styles) {
            for (var key in styles) {
                el.style[key] = styles[key];
            }
        }

        for (let index = 0; index < 100; index++) {
            div = document.createElement('div');
            div.id = index;
            document.body.appendChild(div);

            var color = Generate_contrast_color(7, 4.5, 21);
            var color1 = color[0];
            var color2 = color[1];
            var ContrastRatio = color[2];

            var span = document.createElement("span");
            span.innerText = "文本文字";
            setStyle(span, {
                display: 'inline-block',
                padding: '10px',
                margin: '30px',
                textAlign: 'center',
                color: color1,
                'background-color': color2
            });

            document.getElementById(index).appendChild(span);

            span = document.createElement("span");
            var text = "  文字颜色:" + color1 + ' 背景颜色:' + color2 + '; 对比率:' + ContrastRatio;
            span.innerText = text;

            document.getElementById(index).appendChild(span);
        }
    </script>
</body>

</html>

创造不易,麻烦转载留个言

0

评论 (0)

取消