Approx. read time: 2.9 min.
Post: 🎨 Convert RGB to Hexadecimal
🎨 3. Convert RGB to Hexadecimal
:root {
–primary: #00ffcc;
–dark-bg: #0f0f0f;
–light-bg: #ffffff;
}
body {
background: var(–dark-bg);
margin: 0;
font-family: ‘Courier New’, monospace;
}
#colorConverter {
max-width: 720px;
margin: 30px auto;
padding: 20px;
background: linear-gradient(135deg, #0f0f0f, #1a1a1a);
color: var(–primary);
border: 2px solid var(–primary);
border-radius: 16px;
box-shadow: 0 0 25px rgba(0, 255, 204, 0.3);
position: relative;
}
input,
button {
background: linear-gradient(145deg, #1d1d1d, #111);
color: var(–primary);
border: 1px solid var(–primary);
border-radius: 6px;
padding: 8px;
width: 100%;
font-size: 14px;
}
input[type=”range”] {
padding: 0;
}
button {
cursor: pointer;
transition: all 0.3s ease;
}
button:hover {
background: var(–primary);
color: #000;
}
.input-group {
flex: 1;
min-width: 100px;
}
.row {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: space-between;
}
.swatch, .history-swatch {
width: 30px;
height: 30px;
border-radius: 6px;
box-shadow: 0 0 6px rgba(0, 255, 204, 0.4);
cursor: pointer;
}
#clipboardMessage {
position: absolute;
top: -10px;
right: 10px;
background: var(–primary);
color: #000;
padding: 6px 12px;
border-radius: 6px;
opacity: 0;
transition: opacity 0.5s ease, transform 0.5s ease;
transform: translateY(-10px);
font-size: 14px;
}
#clipboardMessage.show {
opacity: 1;
transform: translateY(0);
}
#lockRow {
display: flex;
justify-content: space-between;
gap: 10px;
margin-top: 6px;
}
.lock-toggle {
font-size: 20px;
cursor: pointer;
text-align: center;
user-select: none;
}
.lock-toggle.locked {
color: #ff6699;
}
#harmonyButtons button {
padding: 4px 8px;
font-size: 12px;
}
#liveDot {
width: 14px;
height: 14px;
border-radius: 50%;
border: 2px solid var(–primary);
box-shadow: 0 0 10px rgba(0,255,204,0.5);
margin-left: 6px;
}
#textPreview {
margin-top: 12px;
padding: 10px;
border-radius: 6px;
}
🎨 RGB ⇄ HEX Color Converter
🎨 Shades & Tints:
const $ = id => document.getElementById(id);
const [r, g, b] = [‘r’,’g’,’b’].map($);
const [rr, gr, br] = [‘rRange’,’gRange’,’bRange’].map($);
const hex = $(‘hex’), preview = $(‘colorPreview’);
const result = $(‘resultInfo’), contrast = $(‘contrastInfo’);
const msg = $(‘clipboardMessage’), palette = $(‘palette’), hist = $(‘history’);
const bgToggle = $(‘bgToggle’), liveDot = $(‘liveDot’), textPreview = $(‘textPreview’);
const colorPicker = $(‘colorPicker’);
let darkBG = true, historyColors = [];
const locks = { r: false, g: false, b: false };
function componentToHex(c) {
const hex = c.toString(16);
return hex.length === 1 ? ‘0’ + hex : hex;
}
function rgbToHex(r, g, b) {
return ‘#’ + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function hexToRgb(hx) {
hx = hx.replace(/^#/, ”);
if (hx.length === 3) hx = hx.split(”).map(c => c + c).join(”);
if (!/^[0-9a-f]{6}$/i.test(hx)) return null;
const int = parseInt(hx, 16);
return { r: (int >> 16) & 255, g: (int >> 8) & 255, b: int & 255 };
}
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r,g,b), min = Math.min(r,g,b);
let h, s, l = (max + min) / 2;
if(max === min) h = s = 0;
else {
const d = max – min;
s = l > 0.5 ? d/(2 – max – min) : d/(max + min);
switch(max) {
case r: h = (g – b)/d + (g {
if (![‘r’,’g’,’b’][i] || !locks[[‘r’,’g’,’b’][i]]) el.value = [rVal, gVal, bVal][i];
});
updatePreview(rVal, gVal, bVal);
}
function updateFromHex() {
const rgb = hexToRgb(hex.value);
if (!rgb) return;
if (!locks.r) { r.value = rgb.r; rr.value = rgb.r; }
if (!locks.g) { g.value = rgb.g; gr.value = rgb.g; }
if (!locks.b) { b.value = rgb.b; br.value = rgb.b; }
updatePreview(+r.value, +g.value, +b.value);
}
function updateContrast(r, g, b) {
const L = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
const cBlack = (L + 0.05) / 0.05;
const cWhite = 1.05 / (L + 0.05);
const ratio = Math.max(cBlack, cWhite).toFixed(2);
const best = cBlack > cWhite ? ‘Black Text’ : ‘White Text’;
const level = ratio >= 7 ? ‘AAA’ : ratio >= 4.5 ? ‘AA’ : ratio >= 3 ? ‘AA Large’ : ‘Fail’;
contrast.innerText = `🧪 Best contrast: ${best} | Contrast: ${ratio}:1 | WCAG: ${level}`;
}
function copyColor(type) {
const hexVal = hex.value;
const rgbVal = `rgb(${r.value}, ${g.value}, ${b.value})`;
const val = type === ‘hex’ ? hexVal : rgbVal;
navigator.clipboard.writeText(val).then(showMsg);
}
function copyExport() {
navigator.clipboard.writeText(`–my-color: ${hex.value};`).then(showMsg);
}
function downloadExport() {
const json = JSON.stringify({
hex: hex.value,
rgb: `rgb(${r.value}, ${g.value}, ${b.value})`,
hsl: rgbToHsl(+r.value, +g.value, +b.value)
}, null, 2);
const a = document.createElement(‘a’);
a.href = URL.createObjectURL(new Blob([json], { type: ‘application/json’ }));
a.download = ‘color.json’;
a.click();
}
function showMsg() {
msg.classList.add(‘show’);
setTimeout(() => msg.classList.remove(‘show’), 1500);
}
function updatePalette(r, g, b) {
palette.innerHTML = ”;
for (let i = 0.2; i setHex(hx);
palette.appendChild(swatch);
}
}
function updateHistory(hexVal) {
if (historyColors.includes(hexVal)) return;
historyColors.unshift(hexVal);
if (historyColors.length > 5) historyColors.pop();
hist.innerHTML = ”;
historyColors.forEach(hx => {
const el = document.createElement(‘div’);
el.className = ‘history-swatch’;
el.style.background = hx;
el.title = `Copy ${hx}`;
el.onclick = () => navigator.clipboard.writeText(hx).then(showMsg);
el.tabIndex = 0;
el.setAttribute(‘aria-label’, `History color ${hx}`);
hist.appendChild(el);
});
}
function setHex(hx) {
hex.value = hx;
updateFromHex();
}
function saveToLocal(hx) {
localStorage.setItem(‘colorPickerColor’, hx);
}
function loadFromLocal() {
return localStorage.getItem(‘colorPickerColor’);
}
function resetAll() {
[r.value, g.value, b.value] = [0, 0, 0];
[rr.value, gr.value, br.value] = [0, 0, 0];
hex.value = ‘#000000’;
updatePreview(0, 0, 0);
localStorage.removeItem(‘colorPickerColor’);
}
bgToggle.onclick = () => {
darkBG = !darkBG;
preview.style.background = darkBG ? ‘#333’ : ‘#fff’;
preview.style.border = darkBG ? ‘none’ : ‘1px solid #000’;
};
const n = $(c), s = $(c+’Range’), lockBtn = $(‘lock’ + c.toUpperCase());
n.addEventListener(‘input’, updateFromRGB);
n.addEventListener(‘keydown’, e => {
if ([‘ArrowUp’,’ArrowDown’].includes(e.key)) {
if (!locks[c]) {
n.value = +n.value + (e.key === ‘ArrowUp’ ? 1 : -1);
updateFromRGB();
}
}
});
s.addEventListener(‘input’, () => {
if (!locks[c]) {
n.value = s.value;
updateFromRGB();
}
});
lockBtn.onclick = () => {
locks[c] = !locks[c];
lockBtn.innerText = locks[c] ? ‘🔒’ : ‘🔓’;
lockBtn.classList.toggle(‘locked’, locks[c]);
};
});
hex.addEventListener(‘input’, updateFromHex);
hex.addEventListener(‘paste’, () => setTimeout(updateFromHex, 10));
colorPicker.addEventListener(‘input’, e => setHex(e.target.value));
function applyHarmony(type) {
const rgb = { r: +r.value, g: +g.value, b: +b.value };
const baseHSL = rgbToHSLParts(rgb.r, rgb.g, rgb.b);
let h = baseHSL.h;
if (type === ‘complementary’) h = (h + 180) % 360;
if (type === ‘analogous’) h = (h + 30) % 360;
if (type === ‘triadic’) h = (h + 120) % 360;
const newRGB = hslToRgb(h, baseHSL.s, baseHSL.l);
setHex(rgbToHex(…newRGB));
}
function rgbToHSLParts(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b), min = Math.min(r, g, b);
let h = 0, s, l = (max + min) / 2;
if (max === min) s = 0;
else {
const d = max – min;
s = l > 0.5 ? d / (2 – max – min) : d / (max + min);
switch (max) {
case r: h = ((g – b) / d + (g < b ? 6 : 0)) * 60; break;
case g: h = ((b – r) / d + 2) * 60; break;
case b: h = ((r – g) / d + 4) * 60; break;
}
}
return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };
}
function hslToRgb(h, s, l) {
s /= 100; l /= 100;
const C = (1 – Math.abs(2 * l – 1)) * s;
const X = C * (1 – Math.abs((h / 60) % 2 – 1));
const m = l – C/2;
let r = 0, g = 0, b = 0;
if (0 <= h && h < 60) [r, g, b] = [C, X, 0];
else if (60 <= h && h < 120) [r, g, b] = [X, C, 0];
else if (120 <= h && h < 180) [r, g, b] = [0, C, X];
else if (180 <= h && h < 240) [r, g, b] = [0, X, C];
else if (240 <= h && h < 300) [r, g, b] = [X, 0, C];
else if (300 <= h && h {
const urlHex = new URLSearchParams(location.search).get(‘color’);
if (urlHex && hexToRgb(urlHex)) return setHex(urlHex);
const saved = loadFromLocal();
if (saved && hexToRgb(saved)) return setHex(saved);
updateFromRGB();
});
✅ What It Does
This one-liner converts RGB color values (Red, Green, Blue — each from 0–255) into a single hexadecimal color code like #0033ff
, which is widely used in CSS and digital design.
🧠 Why It’s Useful
-
Most design tools and CSS stylesheets use hexadecimal color notation.
-
However, many apps (like color pickers, image editors, or canvas APIs) give you RGB values.
-
This one-liner helps you bridge the gap quickly, converting RGB to a Hex code programmatically.
🧪 How It Works — Step by Step
Example:
1. Bit Shifting & Packing:
-
1 << 24
= 16777216 ensures that the resulting number has a leading1
to preserve full 6-digit hex output even when R, G, or B is 0. -
(r << 16)
shifts red into the first two hex digits -
(g << 8)
shifts green into the middle two -
b
stays in the last two
For example:
-
r = 0 → 0x00
-
g = 51 → 0x33
-
b = 255 → 0xff
-
Combined:
#0033ff
2. Convert to Hex:
This converts the full number into a hexadecimal string like "10033ff"
.
3. Remove the leading 1:
Trims off the extra “1” added earlier to ensure zero-padding.
4. Add the hash:
🛠️ Alternate (Readable) Version
If you prefer clarity over brevity:
This version uses .padStart()
for guaranteed 2-digit output and is more readable for beginners.
🎯 Real-World Use Cases
-
Color pickers
-
CSS generation tools
-
Image editors or pixel manipulation
-
Canvas drawing apps
-
UX theming engines
🧾 Final Summary: Mastering RGB to Hex Conversion in JavaScript
Converting RGB values to hexadecimal color codes may seem like a simple task, but it’s an essential bridge between programmatic color generation and visual design standards in the web ecosystem.
This one-liner introduces more than just a formatting trick — it demonstrates how JavaScript can be used for bitwise manipulation, data formatting, and precision visual control, all in a single line of code.
🎯 Why It Matters
In design-to-code workflows, color representation is everything. Designers often work in hex codes, while devices, canvas APIs, and user inputs frequently provide RGB. This converter equips you to translate, visualize, and control color output with absolute precision.
Whether you’re building:
-
A custom color picker
-
A theme switcher with programmatically generated palettes
-
A dynamic UI where colors adjust based on data (like graphs or pixel input)
…this utility allows you to move effortlessly between two universal color standards: RGB and hex.
🧠 What You’ve Learned
-
How color is stored and represented in JavaScript
-
How bitwise operators (
<<
) can be leveraged for encoding values -
The importance of preserving formatting with string manipulation
-
The role of hexadecimal color codes in CSS, design systems, and responsive UI development
🌐 Beyond the One-Liner
You’ve also been introduced to the deeper idea that one-liners are not about cleverness — they’re about fluency. Fluency in JavaScript means knowing not just how to solve a problem, but how to do it elegantly, clearly, and in a way that adapts across platforms and use cases.
Understanding the math behind colors unlocks future skills like:
-
Color blending
-
Contrast testing
-
Accessibility (WCAG) improvements
-
Real-time theme generation
By mastering this one-liner, you’re not just converting colors — you’re writing code that speaks the language of designers, devices, and the web itself.
Ready for the next one-liner? Let’s keep building your ultimate JavaScript toolbox.