Regex for Hexadecimal Color Code Validation — 3, 6, and 8-Digit Hex

Hex color inputs show up in theme builders, design tools, and CSS-in-JS configuration — and users paste them in every possible shape: with or without the leading #, shorthand or full length, sometimes uppercase. This guide covers the regex patterns for all common hex color formats, including the alpha-channel variants.

Hex Color Formats

  • 3-digit shorthand#abc — each digit represents a doubled hex pair (R, G, B)
  • 6-digit standard#aabbcc — two hex digits each for red, green, blue
  • 4-digit shorthand with alpha#abcd — RGB shorthand plus one alpha digit
  • 8-digit with alpha#aabbccdd — full RGB plus a two-digit alpha channel

Basic Regex (3 or 6 Digits)

const hexColor = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;

hexColor.test('#1a2b3c');  // true
hexColor.test('1a2b3c');   // true — # is optional
hexColor.test('#abc');     // true — 3-digit shorthand
hexColor.test('#1a2b3');   // false — 5 digits is not a valid length
hexColor.test('#gghhii');  // false — g, h, i are not valid hex characters

Extended Regex with Alpha Channel (4 or 8 Digits)

CSS Color Module Level 4 supports an alpha channel appended directly to the hex string. This pattern covers all four valid lengths — 3, 4, 6, and 8 digits:

const hexColorWithAlpha = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{3})$/;

hexColorWithAlpha.test('#1a2b3c80');  // true — 6-digit color + 2-digit alpha
hexColorWithAlpha.test('#abcd');      // true — 3-digit color + 1-digit alpha
hexColorWithAlpha.test('#1a2b3c8');   // false — 7 digits is not valid

Normalizing and Expanding Shorthand Hex

Once validated, it is often useful to normalize every hex value to the full 6-digit form before storing it, so comparisons and downstream tooling stay consistent:

function normalizeHex(input) {
  const value = input.replace('#', '');

  if (!/^[A-Fa-f0-9]{3}$|^[A-Fa-f0-9]{6}$/.test(value)) {
    throw new Error('Invalid hex color');
  }

  if (value.length === 3) {
    return '#' + value.split('').map((c) => c + c).join('').toLowerCase();
  }

  return '#' + value.toLowerCase();
}

normalizeHex('#abc');     // '#aabbcc'
normalizeHex('1A2B3C');   // '#1a2b3c'

Using the Pattern in a Form Field (React Example)

function ColorInput({ value, onChange }) {
  const isValid = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value);

  return (
    <div>
      <input
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder="#1a2b3c"
        style={{ borderColor: isValid ? '#16a34a' : '#dc2626' }}
      />
      {!isValid && <span>Enter a valid hex color, e.g. #1a2b3c</span>}
    </div>
  );
}

Common Mistakes

  • Forgetting the shorthand 3-digit and 4-digit forms are valid — many patterns online only check for 6 digits
  • Not making the # optional, which rejects valid values pasted without it
  • Using [0-9a-fA-F] without anchors (^/$), which lets partial matches inside longer strings pass validation
  • Confusing CSS named colors ("red", "tomato") with hex codes — validate those separately against a known color-name list if you need to support them

Frequently Asked Questions

What is the regex for validating a hex color code?

The pattern ^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$ matches both 3-digit and 6-digit hex color codes with an optional leading #.

How do I validate hex colors with an alpha channel?

Use ^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$ to match 8-digit (RRGGBBAA) and 4-digit (RGBA shorthand) hex codes that include an alpha/transparency channel.

How do I convert a 3-digit hex shorthand to 6-digit?

Each character in the 3-digit shorthand is duplicated: #abc becomes #aabbcc. In JavaScript this can be done by matching each character and repeating it twice before joining the string back together.

Try the Free AI Regex Generator

Describe any validation rule in plain English and get a working regex instantly — no signup required.

Related articles