CSS Minifier's Color Code Shorthand Rule
If you've used the CSS Minifier, you've probably noticed #ffffff getting shortened to #fff and wondered why some colors shrink while others stay the same length. This shorthand isn't a rough heuristic — it's decided by a single regular expression with a precise, well-defined condition. This guide walks through exactly what that condition is, and why color notations other than hex (rgb, hsl) don't get shortened the same way.
1. The Real Condition for Shrinking a 6-Digit Hex to 3 Digits
Per the CSS spec, the 3-digit hex code #rgb is interpreted exactly the same as the 6-digit form #rrggbb with each digit doubled. In other words, #0f0 is treated internally by the browser identically to #00ff00. Flip that property around, and you get the rule: a 6-digit code can only be safely folded back into 3 digits when each of its R, G, and B digit-pairs happens to consist of the same character repeated twice. The R pair might be "ff", the G pair "00", the B pair "00" — each pair's two characters must match, and all three pairs must satisfy this at once. If even one pair has two different characters, there's no way to represent that information in 3 digits, so the shorthand simply isn't possible.
2. The Actual Matching Logic, in Regex
The regex the CSS Minifier actually uses looks like this.
/#([0-9a-fA-F])\1([0-9a-fA-F])\2([0-9a-fA-F])\3\b/g → replaced with '#$1$2$3'Here
\1, \2, and \3 are backreferences — they only match if the exact same character captured moments earlier appears again. In other words, the regex itself enforces the "each digit-pair must repeat the same character" rule as a matter of syntax, not just a description.
Because of this structure, the test is stricter than eyeballing it would suggest. If even a single digit-pair doesn't match, the regex fails to match at all, and the original 6-digit code is passed through untouched.
3. Colors That Shrink vs. Colors That Don't
| Input | Digit pairs | Result | Why |
|---|---|---|---|
| #ffffff | ff / ff / ff | #fff | All three pairs have matching characters |
| #ff0000 | ff / 00 / 00 | #f00 | All three pairs have matching characters |
| #a1b2c3 | a1 / b2 / c3 | Can't shrink (stays as-is) | a≠1, b≠2, c≠3 — all three pairs mismatch |
| #3b82f6 | 3b / 82 / f6 | Can't shrink (stays as-is) | 3≠b, 8≠2, f≠6 — all three pairs mismatch |
#a1b2c3 and #3b82f6 in the table above are typical "can't shrink" cases. When the R pair's two characters differ, the backreference condition (\1) in the regex fails, and the same goes for the G and B pairs — so the whole pattern doesn't match. In practice, most brand colors and design-system color values are arbitrary combinations like these, so far more often than not, a 6-digit code stays exactly as it is. One more thing worth noting: the FAQ copy on the CSS Minifier page itself states that "#ff9933 does not get shortened" — but running it through the actual regex shows otherwise. #ff9933's digit pairs (ff, 99, 33) all have matching characters, so it does get shortened to #f93. The code's actual behavior and the documentation example disagree here, so when you need to determine whether a color will shorten, trust the matching logic in this guide (the regex itself), not that FAQ line.
4. Why rgb() and hsl() Don't Shrink the Same Way
The CSS Minifier's color-shorthand rule is a regex that applies only to hex notation starting with #. Functional notations like rgb(255,255,255) or hsl(0,0%,100%) were never a target of that regex to begin with, so running them through the minifier only tidies up whitespace around the function name, parentheses, and commas — rgb() is never automatically converted into a shorter hex form like #fff. That's because this tool works purely through regex substitution: it never interprets the meaning of a value (the color itself), only its character pattern. If you actually want the smallest possible byte count, you're better off writing #fff directly instead of rgb(255,255,255) in your source. You can convert between notations with the RGB→HEX Converter or the HEX→RGB Converter, but that's a separate tool's job and has nothing to do with the minifier's own color-shorthand rule.
5. Practical Checklist Before You Ship
- If you standardize the hex values in your design tokens (things like
--primary-color) to use shortenable forms (each digit-pair repeated) from the start, your compression ratio goes up automatically. - To check ahead of time whether a value can shrink, just split the 6-digit value into three pairs and check whether each pair's two characters match — that's the exact same logic described above.
- For bigger savings, run the CSS Beautifier first to normalize formatting, then apply minification afterward.
Frequently Asked Questions
Q. Why doesn't #112233 shrink?
It actually does shrink — the R pair is "11", G pair is "22", B pair is "33", and each pair on its own has two matching characters, so it becomes #123. By contrast, something like #123abc has digit-pairs made of different characters (1 and 2, 3 and a, b and c), so that one doesn't shrink.
Q. Does a hex value with mixed case (#FfFfFf) still shrink?
The regex's character class [0-9a-fA-F] recognizes both upper- and lowercase, but the backreference (\1) requires an exact match against the captured character. So if upper- and lowercase are mixed within a pair (e.g. #Ff0000, where F and f are different characters), it won't match and won't shrink.
Q. Does an 8-digit hex with an alpha channel (#ffffffff) shrink too?
This tool's regex only targets the 6-digit pattern (#rrggbb), so an 8-digit code with an alpha channel appended never matches and is left exactly as-is.
Q. Do hex values inside SCSS variables get shortened too?
This tool is a regex-based processor for plain CSS syntax only — it doesn't support SCSS directly. Compile your SCSS down to plain CSS first, and the color-shorthand rule will apply normally after that.