JavaScript - Check If String Is Valid CSS Color

Javascript - check if string is valid CSS color?

Here's a simple function that checks color name support in the current browser:

function isColor(strColor){
var s = new Option().style;
s.color = strColor;
return s.color == strColor;
}

// try it out
isColor("red"); // true
isColor("reds"); // false

Since an invalid CSS property value will not persist, we can compare an attempted set value with the value we meant to set, and if they match, we know the color/property is valid.

Note this will also approve hex, RGB, etc. You can screen those out with a RegExp or two if that's an issue for your application.

Validating css color names

All of the solutions posted on this page are incorrect when the string in question is the same colour as the test colour. Granted, you could use a very unlikely choice of colour, but I would prefer to go for 100% success rate.

OP has a single typo in his code (see condition with colon), and does not test for "#28e32a", so that colour will fail, and the regex will collapse whitespace within the colour, so "#28e 32a" would (incorrectly) pass.

In normal JavaScript, this should have 100% success:

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/

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 end

i -> 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

Combined solution :

var reg=/^#([0-9a-f]{3}){1,2}$/i;
console.log(reg.test('#ABC')); //true
console.log(reg.test('#AABBCC')); //true

How to check String green is valid color or not in Jquery?

You can use following method to validate css color

  1. Create a temporary element
  2. Set any color using css('backgroundColor', 'white')
  3. After apply with the input value as backgroundColor using d.css('backgroundColor', this.value);
  4. Check the the color is changed or entered value is same that we are initially set, in that case it's a valid color

$('#input').keyup(function() {  if (this.value.trim()) {    var d = $('<span/>')      .css('backgroundColor', 'white')      .css('backgroundColor', this.value);    $('#op').html(this.value + (d.css('backgroundColor') == '' && this.value + (d.css('backgroundColor') != 'white' && d.css('backgroundColor') != 'rgb(255, 255, 255)') || /^white$/i.test(this.value) ? ' is valid' : ' is not valid'));  } else    $('#op').empty();});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><input type="text" id="input">
<div id="op"></div>

Javascript - check if string is valid CSS color?

Here's a simple function that checks color name support in the current browser:

function isColor(strColor){
var s = new Option().style;
s.color = strColor;
return s.color == strColor;
}

// try it out
isColor("red"); // true
isColor("reds"); // false

Since an invalid CSS property value will not persist, we can compare an attempted set value with the value we meant to set, and if they match, we know the color/property is valid.

Note this will also approve hex, RGB, etc. You can screen those out with a RegExp or two if that's an issue for your application.

How to type a color prop?

This one is pretty hard to encode in TypeScript's type system. I believe a full fledged parser can do a better job in both speed and accuracy.


Anyway, if you really want to get some typecheking for your color values from typescript then let's start with w3c color property description:

Values: <color value> | <color keyword> | currentColor | transparent | inherit

playground link for those who don't need explanations and what to look right into the code.


Well, color keyword, currentColor, transparent and inherit are pretty straightforward:

type Color = ColorValue | ColorKeyword | 'currentColor' | 'transparent' | 'inherit'

type ColorKeyword =
| "black"
| "silver"
| "gray"
...
| "rebeccapurple"

The tricky part is <color value>:

The color can be specified as

* a hexadecimal RGB value: #faf or #ffaaff
* a RGB value: rgb(255, 160, 255) or rgb(100%, 62.5%, 100%)
Each value is from 0 to 255, or from 0% to 100%.
* a RGBA value: rgba(255, 160, 255, 1) or rgba(100%, 62.5%, 100%, 1)
This variant includes an “alpha” component to allow
specification of the opacity of a color. Values are
in the range 0.0 (fully transparent) to 1.0 (fully opaque).
* a HSL value: hsl(0, 100%, 50%)
A triple (hue, saturation, lightness). hue is an
angle in degrees. saturation and lightness are
percentages (0-100%).
* a HSLA value: hsla(0, 100%, 50%, 1)
This variant includes an “alpha” component to allow
specification of the opacity of a color. Values are
in the range 0.0 (fully transparent) to 1.0 (fully opaque).

hexadecimal RGB value is still ok-ish:

type HexDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'

type Hex3 = `${HexDigit}${HexDigit}${HexDigit}`

type RGBColor<T extends string> =
Lowercase<T> extends `#${Hex3}`
? T
: Lowercase<T> extends `#${Hex3}${infer Rest}`
? Rest extends Hex3
? T
: never
: never

We have to introduce type variable T. Otherwise 'flat' union type:

type RGBColor = `#${Hex3}` | `#${Hex3}${Hex3}`

is going to consist of 16^3 + 16^6 constituents that's far beyound 100000 typescript limit for union types.

Let's introduce some helper types to work with numbers. We have to check the percents are not greater than 100% and end with % character.

type DecDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type Digits0to4 = '0' | '1' | '2' | '3' | '4'

type OnlyDecDigits<T extends string> =
T extends `${DecDigit}${infer Rest}`
? Rest extends ''
? 1
: OnlyDecDigits<Rest>
: never

type IsDecNumber<T extends string> =
T extends `${infer Integer}.${infer Fractional}`
? Integer extends ''
? OnlyDecDigits<Fractional>
: Fractional extends ''
? OnlyDecDigits<Integer>
: OnlyDecDigits<Integer> & OnlyDecDigits<Fractional>
: OnlyDecDigits<T>

type IntegerPart<T extends string> =
T extends `${infer I}.${infer F}`
? I
: T

type IsInteger<T extends string> =
1 extends IsDecNumber<T>
? T extends IntegerPart<T>
? 1
: never
: never

type Less100<T extends string> =
IsDecNumber<T> extends 1
? IntegerPart<T> extends `${DecDigit}` | `${DecDigit}${DecDigit}` | '100'
? 1
: never
: never

type IsPercent<T extends string> =
'0' extends T
? 1
: T extends `${infer P}%`
? Less100<P>
: never

Also color values must be integers and not greater than 255:

type Color255<T extends string> =
1 extends IsInteger<T>
? T extends `${DecDigit}`
| `${DecDigit}${DecDigit}`
| `1${DecDigit}${DecDigit}`
| `2${Digits0to4}${DecDigit}`
| `25${Digits0to4 | '5'}`
? 1
: never
: never

so, any color value can be encoded as an integer number in [0..255] range or a percent:

type IsColorValue<T extends string> = IsPercent<T> | Color255<T>

Adding utility Trim type to trim extra spaces on both ends:

type WhiteSpace = ' '
type Trim<T> = T extends `${WhiteSpace}${infer U}`
? Trim<U>
: T extends `${infer U}${WhiteSpace}`
? Trim<U>
: T;

That's enough for rgb:

type RGB<T extends string> = 
T extends `rgb(${infer R},${infer G},${infer B})`
? '111' extends `${IsColorValue<Trim<R>>}${IsColorValue<Trim<G>>}${IsColorValue<Trim<B>>}`
? T
: never
: never

For rgba/hsla we'll need opacity. Here we just ask for any valid number or a percent:

type Opacity<T extends string> = IsDecNumber<T> | IsPercent<T>

Now we can check rgba values:

type RGBA<T extends string> =
T extends `rgba(${infer R},${infer G},${infer B},${infer O})`
? '1111' extends `${IsColorValue<Trim<R>>}${IsColorValue<Trim<G>>}${IsColorValue<Trim<B>>}${Opacity<Trim<O>>}`
? T
: never
: never

Adding degree checker for hsl/hsla:

type Degree<T extends string> =
1 extends IsInteger<T>
? T extends `${DecDigit}`
| `${DecDigit}${DecDigit}`
| `${'1' | '2'}${DecDigit}${DecDigit}`
| `3${Digits0to4 | '5'}${DecDigit}`
| '360'
? 1
: never
: never

and finally we can cover the last cases:

type HSL<T extends string> =
T extends `hsl(${infer H},${infer S},${infer L})`
? `111` extends `${Degree<Trim<H>>}${IsPercent<Trim<S>>}${IsPercent<Trim<L>>}`
? T
: never
:never

type HSLA<T extends string> =
T extends `hsla(${infer H},${infer S},${infer L},${infer O})`
? `1111` extends `${Degree<Trim<H>>}${IsPercent<Trim<S>>}${IsPercent<Trim<L>>}${Opacity<Trim<O>>}`
? T
: never
:never

So our final type will look like that:

type ColorValue<T extends string> = HexColor<T> | RGB<T> | RGBA<T> | HSL<T> | HSLA<T>

type Color<T extends string> = ColorValue<T> | ColorKeyword | 'currentColor' | 'transparent' | 'inherit'

playground link



Related Topics



Leave a reply



Submit