Skip to content

Instantly share code, notes, and snippets.

@Prinzhorn
Forked from 140bytes/LICENSE.txt
Created May 7, 2012 15:55
Show Gist options
  • Save Prinzhorn/2628611 to your computer and use it in GitHub Desktop.
Save Prinzhorn/2628611 to your computer and use it in GitHub Desktop.
compress hex color string

compress hex color strings

In hex you use three or six digits to define a color. By replacing all six-digit colors with the closest color which can be expressed with three digits, we save 3 bytes each! Hooray!

http://www.w3.org/TR/CSS2/syndata.html#value-def-color

The three-digit RGB notation (#rgb) is converted into six-digit form (#rrggbb) by replicating digits, not by adding zeros.

Examples:

'00ff00' -> '0f0'

'34cf9d' -> '3c9'

function a(b, c) {
return ++c ?
(("0x" + b) / 17 + .5 | 0).toString(16) :
b.replace(/../g, a)
}
function a(b,c){return++c?(("0x"+b)/17+.5|0).toString(16):b.replace(/../g,a)}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2012 Alexander Prinzhorn (@Prinzhorn) https://github.com/Prinzhorn
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "hexGolfer",
"description": "Compress hex color strings by using three instead of six digits.",
"keywords": [
"color",
"hex",
"compress"
]
}
<!DOCTYPE html>
<title>Foo</title>
<div style="background:#34cf9d;">Original value: #<b>34cf9d</b></div>
<div style="background:#3c9;">Expected value: #<b>3c9</b></div>
<div>Actual value: #<b id="ret"></b></div>
<script>
// write a small example that shows off the API for your example
// and tests it in one fell swoop.
var myFunction = function a(b,c){return++c?(("0x"+b)/17+.5|0).toString(16):b.replace(/../g,a)}
var ret = document.getElementById( "ret" );
var color = myFunction('34cf9d');
ret.innerHTML = color;
ret.parentNode.style.background = '#' + color;
</script>
@maettig
Copy link

maettig commented May 18, 2012

Nice one. Reminds me of my CSS Color Converter. I tried to start from scratch but came up with the same solution in the end. Good work. What about spending a few bytes to make this work with values like "#34cf9d" and "#3c9"?

function a(b,c){return++c?(("0x"+b)/17+.5|0).toString(16):b[5]?b.replace(/\w\w/g,a):b}

@Prinzhorn
Copy link
Author

The idea was to have a meta function which finds all /#([0-9a-f]{6})/i inside the CSS file and passes it to this function. Could then be used in stuff like CSS minifiers as an option (because it's destructive).

This could of course all fit in 140 bytes combined ;-)

@maettig
Copy link

maettig commented May 18, 2012

Non-destructive version:

function(a){return a.replace(/(\w)\1(.)\2(.)\3/i,'$1$2$3')}

@subzey
Copy link

subzey commented Jun 9, 2012

This version is slightly shorter, also non-destructive

function(a,b){return(b=a.split(/(.)\1/i))[5]?b.join(''):a}

@Prinzhorn
Copy link
Author

@subzey the point is to be destructive. I already gave '34cf9d' -> '3c9' as an example.

The non-destructive version is a different problem. Maybe this should be separated.

@subzey
Copy link

subzey commented Jun 11, 2012

Oh, sorry. I missed that.

Maybe then something like this?

function(a){return a.split(/(\w)./).join('')}

@maettig
Copy link

maettig commented Jun 11, 2012

No, this will turn F0F0F0 into FFF which is wrong. See similar suggestions in the comments above.

@atk
Copy link

atk commented Jun 11, 2012

If we want this to be completely non-destructive, we can only change #000000 to #000, #000011 to #001, ... #111111 to #111 ... #FFFFFF to #FFF, almost as in Subzey's first approach (which would go wrong on colors like #099330:

function(a){return a.replace(/(\w)\1(\w)\2(\w)\3/,"$1$2$3")}

But as we wanted to get the closest color (as is specified in the readme), the original approach (with function body reusal) works best.

@maettig
Copy link

maettig commented Jun 11, 2012

That's what I suggested a few comments above. Mine is even shorter. ;-) Edit: And I added /i to fetch stuff like FffFFf.

@atk
Copy link

atk commented Jun 12, 2012

Ah, I've seen it; you've substituted the 2 last \w with dots.

@yckart
Copy link

yckart commented Aug 25, 2013

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