【问题标题】:Validating css color names验证 CSS 颜色名称
【发布时间】:2025-12-26 23:35:06
【问题描述】:

我编写了一个 jQuery 插件,它的一些参数接受 css 颜色。

我想验证它们。如果它只是一个 hex 或 rgb 值,我可以使用正则表达式来做到这一点,但是如何验证所有 147 个有效颜色名称而不会使插件膨胀?

我想知道是否有某种方法可以尝试应用样式(可能使用 jquery),然后如果它无效则从浏览器中捕获错误?

编辑:powtac 和 Pantelis 提出了一个解决方案,但他们都错过了边缘情况,所以我在这里提供了一个完整的解决方案:

var validateCssColour = function(colour){
    var rgb = $('<div style="color:#28e32a">');     // Use a non standard dummy colour to ease checking for edge cases
    var valid_rgb = "rgb(40, 227, 42)";
    rgb.css("color", colour);
    if(rgb.css('color') == valid_rgb && colour != ':#28e32a' && colour.replace(/ /g,"") != valid_rgb.replace(/ /g,""))
        return false;
    else
        return true;
};

【问题讨论】:

标签: javascript jquery css


【解决方案1】:

我知道这个问题已经相当老了,但我想出了一个纯 JavaScript 解决方案,用于检查似乎在每个浏览器中都可以使用的颜色,并想分享它

此函数使用浏览器将任何输入字符串转换为 CSS 颜色字符串(如果可能)

function getColorCSS(c) {
    const ele = document.createElement("div");
    ele.style.color = c;
    return ele.style.color.replace(/\s+/,'').toLowerCase();
}

更新:使用浏览器本身呈现颜色字符串的美妙之处在于它可以继续使用更新的格式,例如 8 digit hex(其中最后 2 位数字代表 alpha)...


我们来看看基于不同输入的函数输出...

无效输入

基本上,只要浏览器无法弄清楚如何将输入字符串呈现为颜色,就会返回empty string,这使得这个小函数非常适合检测无效颜色字符串!

  • redd, #f0gf0g, #1234, f00, rgb(1,2), rgb(1,2,3.0), rgb(1,2,3,4), rgba(100,150,200)

    • 。 . .
    • 。 . . 火狐
    • 。 . . 互联网浏览器

 

有效输入

  • tomato

    • tomato 。 . .
    • tomato 。 . . 火狐
    • tomato 。 . . 互联网浏览器

 

  • #f00, #ff0000, rgb(255,0,0)

    • rgb(255,0,0) 。 . .
    • rgb(255,0,0) 。 . . 火狐
    • rgb(255,0,0) 。 . . 互联网浏览器

 

  • rgba(255,0,0,1.0), rgba(255,0,0,100)

    • rgb(255,0,0) 。 . . chromergba 转换为 rgb 任何时候 alpha 为 1.0 或更大,因为它无论如何都是完全不透明的(可能是为了性能)
    • rgb(255,0,0) 。 . . firefox 和 chrome 做同样的事情
    • rgba(255,0,0,1) 。 . . internet explorer 将 alpha 参数从 1.0 或更高版本转换为 1

 

  • rgba(0,255,0,0.5)

    • rgba(0,255,0,0.498039) 。 . . chrome 返回的内容与其他浏览器不同(可能以准确性换取性能)
    • rgba(0,255,0,0.5) 。 . . 火狐
    • rgba(0,255,0,0.5) 。 . . 互联网浏览器

 

  • rgba(0,0,255,0.0), rgba(0,0,255,-100)

    • rgba(0,0,255,0) 。 . . chrome 将 alpha 参数从 0.0 或更低转换为 0
    • rgba(0,0,255,0) 。 . . firefox 也是如此
    • rgba(0,0,255,0) 。 . . Internet Explorer 也是如此

 

  • rgba(0,0,0,0), rgba(0,0,0,-100)

    • rgba(0,0,0,0) 。 . .
    • transparent 。 . . firefox 仅将这一个 rgba 实例转换为所有参数设置为 0 的单词 transparent(奇怪)
    • rgba(0,0,0,0) 。 . . 互联网浏览器

 

  • hsl(180,50%,50%)

    • rgb(63,191,191) 。 . .
    • ff rgb(63,191,191) 。 . . 火狐
    • hsl(180,50%,50%)。 . . 互联网浏览器

 

  • hsl(x,x,0%)

    • rgb(0,0,0) 。 . .
    • rgb(0,0,0) 。 . . 火狐
    • hsl(0,0%,0%) 。 . . Internet Explorerblack 的任何 hsl 表示形式转换为此

 

  • hsl(x,x,100%)

    • rgb(255,255,255) 。 . .
    • rgb(255,255,255) 。 . . 火狐
    • hsl(0,0%,100%) 。 . . Internet Explorerwhite 的任何 hsl 表示形式转换为此

 

  • hsla(180,50%,50%,1.0), hsla(180,50%,50%,100)

    • rgba(63,191,191,1) 。 . .
    • rgba(63,191,191,1) 。 . . 火狐
    • hsla(180,50%,50%,1) 。 . . 互联网浏览器

 

  • hsla(180,50%,50%,0.5)

    • rgba(63,191,191,0.498039) 。 . .
    • rgba(63,191,191,0.5) 。 . . 火狐
    • hsla(180,50%,50%,0.5) 。 . . 互联网浏览器

 

  • hsla(0,0%,0%,0.0), hsla(0,0%,0%,-100)

    • rgba(0,0,0,0) 。 . .
    • transparent 。 . . firefox 是一致的,但这种转换仍然看起来很奇怪
    • hsla(180,50%,50%,0) 。 . . 互联网浏览器

哇,我简直不敢相信我只花了 2 个小时在不同的浏览器中测试该功能!

我想我也可以在使用该功能时演示一下...

function getColorCSS(c) {
    var ele = document.createElement("div");
    ele.style.color = c;
    return ele.style.color.split(/\s+/).join('').toLowerCase();
}

function isColorValid(c) {
    var s = getColorCSS(c);
    return (s) ? true : false;
}

function isColorTransparent(c) {
    var s = getColorCSS(c);
    return (
        s === "transparent" || 
        s.substring(0,4) === "rgba" && +s.replace(/^.*,(.+)\)/,'$1') <= 0 ||
        s.substring(0,4) === "hsla" && +s.replace(/^.*,(.+)\)/,'$1') <= 0
    );
}

function isColorWhite(c) {
    var s = getColorCSS(c);
    return [
        "white",
        "rgb(255,255,255)",
        "rgba(255,255,255,1)",
        "hsl(0,0%,100%)",
        "hsla(0,0%,100%,1)"
    ].indexOf(s) > -1;
}

function isColorBlack(c) {
    var s = getColorCSS(c);
    return [
        "black",
        "rgb(0,0,0)",
        "rgba(0,0,0,1)",
        "hsl(0,0%,0%)",
        "hsla(0,0%,0%,1)"
    ].indexOf(s) > -1;
}

function checkColorString() {
  var c = document.getElementById("c").value;
  
  if (c === "") {
    document.getElementsByTagName("body")[0].style.backgroundColor = 'transparent';
    document.getElementById("result").innerHTML = '';
  }
  else if (isColorValid(c)) {
    if (isColorTransparent(c)) {
      document.getElementsByTagName("body")[0].style.backgroundColor = 'transparent';
      document.getElementById("result").innerHTML = '<span style="color:#dadada;">TRANSPARENT</span>';
    }
    else if (isColorWhite(c)) {
      document.getElementsByTagName("body")[0].style.backgroundColor = getColorCSS(c);
      document.getElementById("result").innerHTML = '<span style="color:black;">WHITE</span>';
    }
    else if (isColorBlack(c)) {
      document.getElementsByTagName("body")[0].style.backgroundColor = getColorCSS(c);
      document.getElementById("result").innerHTML = '<span style="color:white;">BLACK</span>';
    }
    else {
      document.getElementsByTagName("body")[0].style.backgroundColor = getColorCSS(c);
      document.getElementById("result").innerHTML = getColorCSS(c);
    }
  }
  else {
    document.getElementsByTagName("body")[0].style.backgroundColor = 'transparent';
    document.getElementById("result").innerHTML = '<span style="font-size:42px;color:#dadada;">&#9785</span>';
  }
}

var eventList = ["change", "keyup", "paste", "input", "propertychange"];
for(event of eventList) {
    document.getElementById("c").addEventListener(event, function() {
      checkColorString();
    });
}
#c {
  width: 300px;
  padding: 6px;
  font-family: courier;
}

#result {
  font-family: courier;
  font-size: 24px;
  padding: 12px 6px;
}
<input id="c" placeholder="Enter any valid CSS color..."></input>
<div id="result"></div>

【讨论】:

  • 一件事我不明白...为什么str.split(/\s+/).join("") 而不是简单的str.replace(/\s+/g, "")
  • 不知何故,如果有人真的讨厌每次都创建元素,您可以尝试document.head.style.color(但如果您的页面不幸没有头部则不行),例如:return [document.head.style.color = "I am color", document.head.style.color][1](我相信不需要更换空间。
  • 好电话 — 我更新了函数以进行替换而不是拆分/加入。
  • @Valen — 替换空格可能有点过头了,但由于我无法控制每个浏览器返回的内容,我认为最好删除空格以确保无效转换返回错误的内容
【解决方案2】:

疯狂的想法

function isValidCssColor(c){
    // put !! to normalize to boolean
    return [
            document.head.style.color = c,
            document.head.style.color,
            document.head.style.color = null
    ][1]; // split it in 3 lines is fine, see snippet
}

我相信它有效(仅当您的页面没有 head 元素时,不知何故)

function isValidCssColor(c){
  document.head.style.color = c;
  let result = document.head.style.color;
  document.head.style.color = null;
  return result;
}

console.log(isValidCssColor("asdf"));       // <empty string>
console.log(isValidCssColor("black"));      // black
console.log(isValidCssColor("#abcdee"));    // rgb(171, 205, 238) // this is browser dependent I guess
console.log(isValidCssColor("asssdf"));     // <empty string>

【讨论】:

  • 这不起作用。它只返回最后一次成功调用的值。我喜欢设置头部元素颜色的想法!
  • @SteveBennett ez fix
【解决方案3】:

短 JavaScript 版本

受 Valen 回答的启发:

v=c=>((s=document.head.style).color=c,q=s.color,s.color='',!!q);
// v('red') => true
// v('reeeed') => false

更具可读性:

const validColor = c => {
  document.head.style.color = c;
  const q = document.head.style.color;
  document.head.style.color = '';
  return !!q
};

【讨论】:

    【解决方案4】:

    function test(myColor) {
      var valid = $('#test').css('color');
    
      $('#test').css('color', myColor);
    
      if (valid == $('#test').css('color')) alert("INVALID COLOR");
      else {
        alert("VALID");
        $('#test').css('color', valid);
      }
    }
    
    
    test("TATATA");
    test("white");
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="test">asdasdasdasd</div>

    虽然写的很仓促,但是很有效。

    【讨论】:

    • black 失败...但您可以检查:if (color == "black") OK else validation_code
    • 是的,你是 100% 正确的。它失败了,因为它检查了 valid== $('#test').css('color') 并且黑色是它的默认值。它可以用你提到的方式修复。谢谢!
    • 谢谢。您的想法与 powtacs 相同。只有他比你早 30 秒左右到达那里,所以我授予他荣誉。这是一个很好的解决方案。
    【解决方案5】:

    当相关字符串的颜色与测试颜色相同时,此页面上发布的所有解决方案都不正确。当然,您可以使用非常不可能的颜色选择,但我更愿意选择 100% 的成功率。

    OP 在他的代码中有一个错字(见冒号的条件),并且不测试“#28e32a”,所以颜色会失败,正则表达式会折叠颜色中的空白,所以“#28e 32a”会(错误地)通过。

    在普通的 JavaScript 中,这应该有 100% 的成功:

    function validTextColour(stringToTest) {
        //Alter the following conditions according to your need.
        if (stringToTest === "") { return false; }
        if (stringToTest === "inherit") { return false; }
        if (stringToTest === "transparent") { return false; }
    
        var image = document.createElement("img");
        image.style.color = "rgb(0, 0, 0)";
        image.style.color = stringToTest;
        if (image.style.color !== "rgb(0, 0, 0)") { return true; }
        image.style.color = "rgb(255, 255, 255)";
        image.style.color = stringToTest;
        return image.style.color !== "rgb(255, 255, 255)";
    }
    

    JSFiddle:http://jsfiddle.net/WK_of_Angmar/xgA5C/

    【讨论】:

    • 我喜欢你的思路,但是对于 "rgb(0,0,0)" 失败了
    • 为什么你有最后两行而不是return false
    • 那是因为我漏掉了一行(见编辑)。最后两行基本上是针对带有或不带空格的“rgb(0,0,0)”的情况。换句话说,我们首先假设用户给定的颜色不是白色,所以如果图像的颜色发生了变化,它就是一个有效的输入。最后两行假设它可能是一个有效的输入,但它是白色的,所以图像的颜色应该从黑色变为其他颜色。
    • 它现在应该适用于 "rgb(0,0,0)" - 中间有或没有空格。
    • 输入#000black时仍然无法正常工作,你的函数有种族问题
    【解决方案6】:

    您可以简单地将颜色设置为虚拟元素,然后检查元素的值是否不是白色。

    colorToTest = 'lime'; // 'lightgray' does not work for IE
    
    $('#dummy').css('backgroundColor', 'white');
    $('#dummy').css('backgroundColor', colorToTest);
    if ($('#dummy').css('backgroundColor') != 'rgb(255, 255, 255)' || colorToTest == 'white') {
        alert(colorToTest+' is valid');
    }
    

    【讨论】:

    • 谢谢。我要做一个修改;对只能用六位十六进制或 rgb 表示的支票使用非标准颜色。您的代码会因 colorToTest = '#fff' 和 '#ffffff' 而失败。使用非标准颜色可以简化它。
    • 在检查 rgb 值时还需要包含去除空格。
    • 对此的调整是将颜色和背景颜色字段设置为新颜色。如果之后两个 CSS 元素相同,那么这是一个有效的颜色。
    【解决方案7】:

    我认为您可以使用page 中的脚本,它完全符合您的要求:您将一个字符串传递给它并尝试找出颜色。好的,这不完全是您想要做的,但它应该可以工作。

    我认为在任何情况下,您都应该进行名称查找(我认为没有什么神奇的方法可以从字符串“浅蓝色”中确定十六进制值),所以只需抢夺其他人的工作已经完成(脚本是 Stoyan Stefanov 编写的,非常擅长 javascript,我从他那里读过一些好书,如果他进行查找,我认为没有其他解决方案)

    【讨论】: