CSS 颜色模式及颜色模式转换器

CSS颜色模式

赏心悦目的颜色搭配让人感到舒服,修改元素颜色的功能让人趋之若鹜。但颜色规划不当,会让网站用户无所适从。颜色从<font color="">发展至今,保留了很多内容,也增加了新的内容。


[1] 传统颜色模式

以前主要采用关键字、16进制和RGB这三种设置颜色的方式。CSS3出现后,增加了RGBA、HSL、HSLA这三种模式,极大地丰富了CSS颜色设置的方式。

1. 关键字

CSS颜色关键字包括命名颜色、transparent、currentColor属性值。

命名颜色

直接使用的名字的颜色值称为命名颜色。CSS支持17种合法命名颜色(标准颜色):

aqua fuchsia lime olive red white black gray maroon orange silver yellow blue green navy purple teal
[注意] 浏览器支持140种颜色

transparent

color: transparent用来表示文本的颜色纯透明,可以近似认为是rgba(0,0,0,0)。

[注意] IE7-不支持color:transparent,但支持background-color: transparent和border-color: transparent。

currentColor

currentColor顾名思义指当前颜色,准确来讲指当前的文字颜色。

[注意]IE8-不支持该属性值。

2. 16进制

16进制是设置颜色值的常用方式,将三个介于00-FF的十六进制数连接起来,若16进制的3组数各自成对,可简写为3位。

#abcdef
#aabbcc <=> #abc

< 安全颜色 >

web安全颜色是指在256色计算机系统上总能避免抖动的颜色,表示为RGB值20%和51(相应的16进制值为33)的倍数。因此,采用16进制时,使用00\33\66\99\cc\ff认为是Web安全色,一共666=216种

3. RGB模式

通过组合不同的红色、绿色、蓝色分量创造出的颜色成为RGB模式的颜色。显示器是由一个个像素构成,利用电子束来表现色彩。像素把光的三原色:红色(R)、绿色(G)、蓝色(B)组合起来。每像素包含8位元色彩的信息量,有0-255的256个单元,其中0是完全无光状态,255是最亮状态。

rgb(x%,y%,z%)
rgb(a,b,c)

[注意]若数值小于最小值0,则默认调整为0;若数值大小最大值255,则默认调整为255。


[2] RGBA模式

rgba模式是在RGB基础上增加了alpha通道,用来设置颜色的透明度,其中这个通道值的范围是0-1。0代表完全透明,1代表完全不透明。

[注意] IE8-浏览器不支持。

rgba(r,g,b,a)

< IE滤镜 >

IE8-浏览器对新增的颜色模式并不支持,需要使用gradient滤镜。gradient滤镜的前两位表示Alpha透明度值(00-ff),其中00表示全透明,ff表示完全不透明。后六位代表的是RGB模式。

如果使用#A6DADC并且透明度为0.6的透明色(0.6*255=153,转换成16进制是99),用gradient滤镜表示为:

filter:progid:DXImageTransform.Microsoft.gradient(enabled = 'true',startColorstr="#99A6DADC",
endColorstr="#99A6DADC")

[注意] IE滤镜只能兼容背景色,而不能兼容前景色。


[3] HSL模式

HSL模式是通过对色调(H)、饱和度(S)、亮度(L)三个颜色通道的变化以及它们相互的叠加得到各式各样的颜色。HSL标准几乎可以包括人类视力所能感知的所有颜色。

[注意] IE8-浏览器不支持。

hsl(h,s,l)

h:色调(hue)可以为任意整数。0(或360或-360)表示红色,60表示黄色,120表示绿色,180表示青色,240表示蓝色,300表示洋红(当h值大于360时,实际的值等于该值模360后的值)。

s:饱和度(saturation),就是指颜色的深浅度和鲜艳程度。取0-100%范围的值,其中0表示灰度(没有该颜色),100%表示饱和度最高(颜色最鲜艳)。

l:亮度(lightness),取0-100%范围的值,其中0表示最暗(黑色),100%表示最亮(白色)。


[4] HSLA模式

HSLA模式是HSL的扩展模式,在HSL的基础上增加一个透明通道alpha来设置透明度。

[注意] IE8-浏览器不支持。

hsla(<length>,<percentage>,<percentage>,<opacity>)

颜色模式转换器

在CSS中,颜色的表示方式主要包括关键字、16进制、RGB模式、RGBA模式、HSL模式、HSLA模式。

如何实现16进制、RGB模式及HSL模式的互相转换?

[1] 16进制 -> RGB

16进制是设置颜色值的常用方式,将三个介于00-FF的十六进制数连接起来,若16进制的3组数各自成对,则可简写为3位。

16进制与RGB模式的对应关系为:16进制的前两位对应RGB的red部分;16进制的中间两位对应RGB的green部分;16进制的后两位对应RGB的blue部分。而16进制使用的16进制的数字格式,而RGB使用的10进制的数字格式。所以还需要数字进制的变换。

function sixteenToRgb(str){
    var r,g,b,rgb;
    if(str.length == 7){
        r = parseInt(str.substr(1,2),16);
        g = parseInt(str.substr(3,2),16);
        b = parseInt(str.substr(5,2),16);
    }else if(str.length == 4){
        r = parseInt('' + str.substr(1,1) + str.substr(1,1),16);
        g = parseInt('' + str.substr(2,1) + str.substr(2,1),16);
        b = parseInt('' + str.substr(3,1) + str.substr(3,1),16);        
    }else{
        return 'false'
    }
    rgb = 'rgb(' + r +',' + g +','+b +')';
    return  rgb;
}
console.log(sixteenToRgb('#123456'));  // rgb(18,52,86)    
console.log(sixteenToRgb('#123'));  // rgb(17,34,51)
console.log(sixteenToRgb('#1234'));  // false

[2] RGB -> 16进制

通过组合不同的红色、绿色、蓝色分量创造出的颜色成为RGB模式的颜色。显示器是由一个个像素构成,利用电子束来表现色彩。像素把光的三原色:红色(R)、绿色(G)、蓝色(B)组合起来。每像素包含8位元色彩的信息量,有0-255的256个单元,其中0是完全无光状态,255是最亮状态。

在RGB模式转换为16进制模式要注意的是,转换的成R、G、B三个分量的16进制值如果是一位数,则需要在前一位补0。

function rgbToSixteen(str){
    var r16,g16,b16,sixteen;
    if(/^rgb\((\d+)\,(\d+)\,(\d+)\)$/.test(str)){
           if( RegExp.$1 >= 0 && RegExp.$1 <=255 || RegExp.$2 >= 0 && RegExp.$2 <=255 || RegExp.$3 >= 0 && RegExp.$3 <=255){
               r16 = addZero(Number(RegExp.$1).toString(16));
               g16 = addZero(Number(RegExp.$2).toString(16));
               b16 = addZero(Number(RegExp.$3).toString(16));
              sixteen = '#' + r16 + g16 + b16 ;
              return  sixteen;
           }else{
               return 'false';
           }
    }else{
        return 'false';
    }
}
function addZero(str){
    if(str.length == 1){
        return '0' + str;
    }else{
        return str;
    }
}
console.log(rgbToSixteen('rgb(10,44,3)'));  // #0a2c03    
console.log(rgbToSixteen('rgb(-10,44,3)'));  // false
console.log(rgbToSixteen('rgb(123)'));  // false

[3] HSL -> RGB

HSL模式是通过对色调(H)、饱和度(S)、亮度(L)三个颜色通道的变化以及它们相互的叠加得到各式各样的颜色。HSL标准几乎可以包括人类视力所能感知的所有颜色。

h:色调(hue)可以为任意整数。0(或360或-360)表示红色,60表示黄色,120表示绿色,180表示青色,240表示蓝色,300表示洋红(当h值大于360时,实际的值等于该值模360后的值)。

s:饱和度(saturation),就是指颜色的深浅度和鲜艳程度。取0-100%范围的值,其中0表示灰度(没有该颜色),100%表示饱和度最高(颜色最鲜艳)。

l:亮度(lightness),取0-100%范围的值,其中0表示最暗(黑色),100%表示最亮(白色)。

// 参考http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
function hslToRgb(str){
    var r, g, b;
    var h, s, l;
    if(/^hsl\((\d+)\,(\d+)%\,(\d+)%\)$/.test(str)){
           if( RegExp.$1 >= 0 && RegExp.$1 <=360 && RegExp.$2 >= 0 && RegExp.$2 <=100 && RegExp.$3 >= 0 && RegExp.$3 <=100){
               h = RegExp.$1/360;
               s = RegExp.$2/100;
               l = RegExp.$3/100;
            if(s == 0){
                r = g = b = l; 
            }else{
                var hue2rgb = function hue2rgb(p, q, t){
                    if(t < 0) t += 1;
                    if(t > 1) t -= 1;
                    if(t < 1/6) return p + (q - p) * 6 * t;
                    if(t < 1/2) return q;
                    if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
                    return p;
                }
                var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
                var p = 2 * l - q;
                r = hue2rgb(p, q, h + 1/3);
                g = hue2rgb(p, q, h);
                b = hue2rgb(p, q, h - 1/3);
            }
            return 'rgb(' + Math.round(r * 255) + ','+ Math.round(g * 255)+ ',' + Math.round(b * 255) + ')';
        }else{
               return 'false';
           }
    }else{
        return 'false';
    }
}
console.log(hslToRgb('hsl(248,64%,39%)')); // rgb(53,36,163)    
console.log(hslToRgb('hsl(-248,64%,39%)')); // false    
console.log(hslToRgb('hsl(300,40%,50%)')); // rgb(179,77,178)

[4] RGB -> HSL

// 参考http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
function rgbToHsl(str){
    var r,g,b;
    if(/^rgb\((\d+)\,(\d+)\,(\d+)\)$/.test(str)){
           if( RegExp.$1 >= 0 && RegExp.$1 <=255 && RegExp.$2 >= 0 && RegExp.$2 <=255 && RegExp.$3 >= 0 && RegExp.$3 <=255){
            r = RegExp.$1/255, g = RegExp.$2/255, b = RegExp.$3/255;
            var max = Math.max(r, g, b), min = Math.min(r, g, b);
            var h, s, l = (max + min) / 2;
            if(max == min){
                h = s = 0; // achromatic
            }else{
                var d = max - min;
                s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
                switch(max){
                    case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                    case g: h = (b - r) / d + 2; break;
                    case b: h = (r - g) / d + 4; break;
                }
                h /= 6;
            }
            return 'hsl(' + Math.round(h*360) + ',' + Math.round(s*100) + '%,' + Math.round(l*100) + '%)';
           }else{
               return 'false';
           }
    }else{
        return 'false';
    }
}
console.log(rgbToHsl('rgb(53,36,163)'));  // hsl(248,64%,39%)
console.log(rgbToHsl('rgb(179,77,178)'));  // hsl(301,40%,50%)
console.log(rgbToHsl('rgb(300,1,1)'));  // false