Skip to content

Instantly share code, notes, and snippets.

@olmokramer
Last active December 9, 2023 12:52
Show Gist options
  • Save olmokramer/82ccce673f86db7cda5e to your computer and use it in GitHub Desktop.
Save olmokramer/82ccce673f86db7cda5e to your computer and use it in GitHub Desktop.
Regex for CSS colors: hex, rgb(a), hsl(a)
/(#([0-9a-f]{3}){1,2}|(rgba|hsla)\(\d{1,3}%?(,\s?\d{1,3}%?){2},\s?(1|0?\.\d+)\)|(rgb|hsl)\(\d{1,3}%?(,\s?\d{1,3}%?\)){2})/i
@xkeshav
Copy link

xkeshav commented Apr 16, 2023

none keyword allowed in latest syntax (while values are space seprated not comma separated ) hen how to capture these

following are valid css

  • rgb(none 10 20)
  • hsl(120deg none none)
  • hwb(200 none 0.5)

@Chasmical
Copy link

Chasmical commented Dec 9, 2023

Here's the regular expression I've got. It recognizes hex-colors and simple color functions. I'm using it in a remarkjs plugin to add color squares next to colors, similar to how GitHub does this: #4F82A9. It might be a bit too big, but it runs on the server for me, so it's fine.

/^(#[0-9a-fA-F]{3,4}|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{8}|rgb\(\s*\d*(?:\.\d*)?\s*,\s*\d*(?:\.\d*)?\s*,\s*\d*(?:\.\d*)?\s*\)|rgba\(\s*(?:\d*(?:\.\d*)?%|0)\s*,\s*(?:\d*(?:\.\d*)?%|0)\s*,\s*(?:\d*(?:\.\d*)?%|0)\s*,\s*\d*(?:\.\d*)?%?\s*\)|rgba?\(\s*\d*(?:\.\d*)?\s*\d*(?:\.\d*)?\s*\d*(?:\.\d*)?\s*(?:\/\s*\d*(?:\.\d*)?%?\s*)?\)|rgba?\(\s*(?:\d*(?:\.\d*)?%|0)\s*(?:\d*(?:\.\d*)?%|0)\s*(?:\d*(?:\.\d*)?%|0)\s*(?:\/\s*\d*(?:\.\d*)?%?\s*)?\)|hsl\(\s*\d*(?:\.\d*)?(?:deg|grad|rad|turn)?\s*,\d*(?:\.\d*)?%\s*,\s*\d*(?:\.\d*)?%\s*\)|hsla\(\s*\d*(?:\.\d*)?(?:deg|grad|rad|turn)?\s*,(?:\d*(?:\.\d*)?%|0)\s*,\s*(?:\d*(?:\.\d*)?%|0)\s*,\s*\d*(?:\.\d*)?%?\s*\)|h(?:sla?|wb)\(\s*\d*(?:\.\d*)?(?:deg|grad|rad|turn)?\s*\d*(?:\.\d*)?\s*\d*(?:\.\d*)?\s*(?:\/\s*\d*(?:\.\d*)?\s*)?\)|h(?:sla?|wb)\(\s*\d*(?:\.\d*)?(?:deg|grad|rad|turn)?\s*(?:\d*(?:\.\d*)?%|0)\s*(?:\d*(?:\.\d*)?%|0)\s*(?:\/\s*\d*(?:\.\d*)?%?\s*)?\))$/

And I'm constructing it like this (JavaScript):

const num = String.raw`\d*(?:\.\d*)?`;
const hue = `${num}(?:deg|grad|rad|turn)?`;

const colorFuncs = [
  // Hex colors: #000, #0000, #000000, #00000000
  `#[0-9a-fA-F]{3,4}`,
  `#[0-9a-fA-F]{6}`,
  `#[0-9a-fA-F]{8}`,
  // Legacy rgb/rgba: rgb(1,2,3), rgba(1,2,3,4)
  String.raw`rgb\(\s*${num}\s*,\s*${num}\s*,\s*${num}\s*\)`,
  String.raw`rgba\(\s*(?:${num}%|0)\s*,\s*(?:${num}%|0)\s*,\s*(?:${num}%|0)\s*,\s*${num}%?\s*\)`,
  // Modern rgb/rgba: rgba(1 2 3 / 0.5)
  String.raw`rgba?\(\s*${num}\s*${num}\s*${num}\s*(?:/\s*${num}%?\s*)?\)`,
  String.raw`rgba?\(\s*(?:${num}%|0)\s*(?:${num}%|0)\s*(?:${num}%|0)\s*(?:/\s*${num}%?\s*)?\)`,
  // Legacy hsl/hsla: hsl(1deg,2%,3%)
  String.raw`hsl\(\s*${hue}\s*,${num}%\s*,\s*${num}%\s*\)`,
  String.raw`hsla\(\s*${hue}\s*,(?:${num}%|0)\s*,\s*(?:${num}%|0)\s*,\s*${num}%?\s*\)`,
  // Modern hsl/hsla/hwb: hsla(1deg 2% 3% / 0.5)
  String.raw`h(?:sla?|wb)\(\s*${hue}\s*${num}\s*${num}\s*(?:/\s*${num}\s*)?\)`,
  String.raw`h(?:sla?|wb)\(\s*${hue}\s*(?:${num}%|0)\s*(?:${num}%|0)\s*(?:/\s*${num}%?\s*)?\)`,
];

export const ColorRegex = new RegExp(`^(${colorFuncs.join("|")})$`);

Here's what this regex doesn't recognize: lab(), lch(), oklab(), oklch(), color(), none keyword, <system-color> type, transparent, currentColor and named colors. Feel free to extend on this one, I'm not planning to, since for my use case I don't need that much specificity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment