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.