How to check if a string is a valid hex color representation?
/^#[0-9A-F]{6}$/i.test('#AABBCC')
To elaborate:
^ ->
match beginning# ->
a hash[0-9A-F] ->
any integer from 0 to 9 and any letter from A to F{6} ->
the previous group appears exactly 6 times$ ->
match endi ->
ignore case
If you need support for 3-character HEX codes, use the following:
/^#([0-9A-F]{3}){1,2}$/i.test('#ABC')
The only difference here is that
[0-9A-F]{6}
is replaced with
([0-9A-F]{3}){1,2}
This means that instead of matching exactly 6 characters, it will match exactly 3 characters, but only 1 or 2 times. Allowing ABC
and AABBCC
, but not ABCD
// regular functionfunction isHexColor (hex) { return typeof hex === 'string' && hex.length === 6 && !isNaN(Number('0x' + hex))}// or as arrow function (ES6+)isHexColor = hex => typeof hex === 'string' && hex.length === 6 && !isNaN(Number('0x' + hex))console.log(isHexColor('AABBCC')) // trueconsole.log(isHexColor('AABBCC11')) // falseconsole.log(isHexColor('XXBBCC')) // falseconsole.log(isHexColor('AAXXCC')) // false
This answer used to throw false positives because instead of Number('0x' + hex)
, it used parseInt(hex, 16)
.parseInt()
will parse from the beginning of the string until it reaches a character that isn't included in the radix (16
). This means it could parse strings like 'AAXXCC', because it starts with 'AA'.
Number()
, on the other hand, will only parse if the whole string matches the radix. Now, Number()
doesn't take a radix parameter, but luckily, you can prefix number literals to get a number in other radii.
Here's a table for clarification:
╭─────────────┬────────────┬────────┬───────────────────╮│ Radix │ Characters │ Prefix │ Will output 27 │╞═════════════╪════════════╪════════╪═══════════════════╡│ Binary │ 0-1 │ 0b │ Number('0b11011') ││ Octal │ 0-7 │ 0o │ Number('0o33') ││ Decimal │ 0-9 │ - │ - ││ Hexadecimal │ 0-9A-F │ 0x │ Number('0x1b') │╰─────────────┴────────────┴────────┴───────────────────╯
This can be a complicated problem. After several attempts I came up with a fairly clean solution. Let the browswer do the the work for you.
Step 1: Create a div with border-style set to none. The div can be positioned off screen or it can be any div on your page that doesn't use the borders.
Step 2: Set the border color to an empty string. The code might look something like this:
e=document.getElementbyId('mydiv');e.style.borderColor="";
Step 3: Set the border color to the color you aren't sure about.
e.style.borderColor=testcol;
Step 4: Check to see if the color actually got changed. If testcol is invalid, no change will occur.
col2=e.style.borderColor;if(col2.length==0) {alert("Bad Color!");}
Step 5: Clean up after yourself by setting the color back to an empty string.
e.style.borderColor="";
The Div:
<div id="mydiv" style="border-style:none; position:absolute; left:-9999px; top:-9999px;"></div>
Now the JavaScript function:
function GoodColor(color){ var color2=""; var result=true; var e=document.getElementById('mydiv'); e.style.borderColor=""; e.style.borderColor=color; color2=e.style.borderColor; if (color2.length==0){result=false;} e.style.borderColor=""; return result;}
In this case, the function is returning a true/false answer to the question, the other option is to have it return a valid color value. Your original color value, the value from borderColor or an empty string in place of invalid colors.