11

I used regex for the hex. /^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ but I dont know what I should for do for finding rgb, rgba and hsl. I am getting the input in string. For example, the input will contain "rgb(0,0,0)"or "rgb(0,0,0,0.2)".

18
  • THx for the great community. This website has been a heaven. Commented Sep 19, 2015 at 22:15
  • do you want to know if it's a color, or what type of color format it is? Commented Sep 19, 2015 at 22:19
  • @dandavis I would like to validate if what the user input is true or not. So I would need to know the type of color format + if it is llegal for that format. I am not converting anything Commented Sep 19, 2015 at 22:32
  • Hi. Take a look at the following site: upshots.org/javascript/javascript-color-class It's a color class. use it or take a look at the code, to see how they parse / validate color values. Commented Sep 19, 2015 at 22:33
  • @JoshuaK it seems it has var isHex = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i; var isHSL = /^hsla?((\d{1,3}?),\s*(\d{1,3}%),\s*(\d{1,3}%)(,\s*[01]?\.?\d*)?)$/; var isRGB = /^rgba?((\d{1,3}%?),\s*(\d{1,3}%?),\s*(\d{1,3}%?)(,\s*[01]?\.?\d*)?)$/; But what should the input LOOK LIKE? Commented Sep 19, 2015 at 22:48

2 Answers 2

20

There are different options here:

1. Use a dummy element

Use the browser's validation. Create a dummy HTML element, assign the color and check if it's set. This is by far the best option. It's not only easier, but it will also allow forward compatibility.

function CheckValidColor(color) {
    var e = document.getElementById('divValidColor');
    if (!e) {
        e = document.createElement('div');
        e.id = 'divValidColor';
    }
    e.style.borderColor = '';
    e.style.borderColor = color;
    var tmpcolor = e.style.borderColor;
    if (tmpcolor.length == 0) {
        return false;
    }
    return true;
}

// function call
var inputOK = CheckValidColor('rgb( 0, 0, 255)');

This will return true for all colors accepted by the browser, even in cases you may consider invalid.


2. Capture the numbers with regex and validate in code

If you capture anything that looks like a number, you will be able to validate each parameter individually with IF clauses. This will allow you to provide better feedback to the user.

a) #hex:

^(#)((?:[A-Fa-f0-9]{3}){1,2})$

The hash is also captured for consistency with the following expression. DEMO

b) rgb(), rgba(), hsl() and hsla():

^(rgb|hsl)(a?)[(]\s*([\d.]+\s*%?)\s*,\s*([\d.]+\s*%?)\s*,\s*([\d.]+\s*%?)\s*(?:,\s*([\d.]+)\s*)?[)]$

This will create captures for the function and each parameter. DEMO


3. Validate with one monster regex:

This option is not recommended, mainly because it's quite difficult to read, it won't guarantee to match all use cases, and it will give you a headache if you try to debug it. The following regex validates the number of parameters allowed and ranges.

a) #hex: ^#(?:[A-Fa-f0-9]{3}){1,2}$ DEMO

b) rgb(): ^rgb[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*(?:,(?![)])|(?=[)]))){3}[)]$ DEMO

c) rgba(): ^^rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*,){3}\s*0*(?:\.\d+|1(?:\.0*)?)\s*[)]$ DEMO

d) hsl(): ^hsl[(]\s*0*(?:[12]?\d{1,2}|3(?:[0-5]\d|60))\s*(?:\s*,\s*0*(?:\d\d?(?:\.\d+)?\s*%|\.\d+\s*%|100(?:\.0*)?\s*%)){2}\s*[)]$ DEMO

e) hsla(): ^hsla[(]\s*0*(?:[12]?\d{1,2}|3(?:[0-5]\d|60))\s*(?:\s*,\s*0*(?:\d\d?(?:\.\d+)?\s*%|\.\d+\s*%|100(?:\.0*)?\s*%)){2}\s*,\s*0*(?:\.\d+|1(?:\.0*)?)\s*[)]$ DEMO

All toghether now:

With the above expressions, we can create this one-liner to validate all legal color values:

^(?:#(?:[A-Fa-f0-9]{3}){1,2}|(?:rgb[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*(?:,(?![)])|(?=[)]))){3}|hsl[(]\s*0*(?:[12]?\d{1,2}|3(?:[0-5]\d|60))\s*(?:\s*,\s*0*(?:\d\d?(?:\.\d+)?\s*%|\.\d+\s*%|100(?:\.0*)?\s*%)){2}\s*|(?:rgba[(](?:\s*0*(?:\d\d?(?:\.\d+)?(?:\s*%)?|\.\d+\s*%|100(?:\.0*)?\s*%|(?:1\d\d|2[0-4]\d|25[0-5])(?:\.\d+)?)\s*,){3}|hsla[(]\s*0*(?:[12]?\d{1,2}|3(?:[0-5]\d|60))\s*(?:\s*,\s*0*(?:\d\d?(?:\.\d+)?\s*%|\.\d+\s*%|100(?:\.0*)?\s*%)){2}\s*,)\s*0*(?:\.\d+|1(?:\.0*)?)\s*)[)])$

DEMO

Or the regex enthusiasts can check this huge regex, with 148 color names. But I would never recommend using that pattern. Please use the first option, creating a dummy element, which is the only way to cover all use cases for the browser.

Sign up to request clarification or add additional context in comments.

2 Comments

Your CheckValidColor() might not work. Since u are checking the tmpcolor.length == 0, length.
So? It will be an empty string if you try to set an incorrect color, hence the length of that string will be == 0... Can you provide an example where it would fail?
0

I dont know about other browsers but in chrome the color will only be set if its valid:

var isValidColor = function(color) {
  var el = document.createElement('div');
  el.style.backgroundColor = color;
  return el.style.backgroundColor ? true : false;
};

console.log(isValidColor('#ff0000')); // true
console.log(isValidColor('rgb(0, 0)')); // false

It will have it's pitfalls though, because Chrome will do auto rounding of numbers:

// 0, 0, 256 is not a valid color, but this says yes
console.log(isValidColor('rgb(0, 0, 256)')); // true

2 Comments

really good answer, about the same as i was going to offer; the only non-brittle solution here. one step further would be to return valid computed properties in the case of an invalid range...
RegExp won't tell you if something works or not, whereas a system like the one above tells you that it actually works. If needed, you can follow up with validity/range restrictions after the well-formed input testing performed by the native color parser.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.