Skip to content

Instantly share code, notes, and snippets.

@VR51
Last active February 14, 2025 05:45
Show Gist options
  • Save VR51/96f51bf0d9b8f34495a32fe87503235b to your computer and use it in GitHub Desktop.
Save VR51/96f51bf0d9b8f34495a32fe87503235b to your computer and use it in GitHub Desktop.
Get all CSS colour codes from the active page. Pop this snippet into your browser Console and press Enter. After pressing Enter a new tab will open showing a table of all colors listed in the CSS of a page.
(function() {
// A product of VR51, Aria and Gemini
const colors = [];
const elements = document.querySelectorAll('*');
elements.forEach(element => {
const styles = window.getComputedStyle(element);
for (let i = 0; i < styles.length; i++) {
const property = styles[i];
if (property.includes('color')) {
const colorValue = styles.getPropertyValue(property);
if (!colors.includes(colorValue)) {
colors.push(colorValue);
}
}
}
});
function colorToNumber(color) {
if (color.startsWith('#')) {
const hex = color.slice(1);
return parseInt(hex, 16);
}
if (color.startsWith('rgb')) {
const rgbValues = color.substring(color.indexOf('(') + 1, color.indexOf(')')).split(',');
let num = 0;
for (let i = 0; i < 3; i++) {
num += parseInt(rgbValues[i].trim()) * (256 ** (2 - i));
}
return num;
}
return color;
}
colors.sort((a, b) => colorToNumber(a) - colorToNumber(b));
function getCssPath(el) {
const selectors = [];
while (el && el.tagName) { // Check if el and el.tagName exist
let selector = el.tagName.toLowerCase();
if (el.id) {
selector += '#' + el.id;
} else if (el.className) {
if (typeof el.className === 'string') { // Check if className is a string
selector += '.' + el.className.split(' ').join('.');
}
}
selectors.unshift(selector);
el = el.parentNode;
}
return selectors.join(' > ');
}
let tableHTML = `<html><head><style>
thead tr {background-color: #009879;color: #ffffff;text-align: left;}
th,td {padding: 12px 15px;}
th:nth-of-type(odd) {width: 220px;}
tbody tr {border-bottom: 1px solid #dddddd;}
tbody tr:nth-of-type(even) {background-color: #f3f3f3;}
tbody td:nth-of-type(even) {background-color: #fff;border: 1px solid #eee;}
tbody td div {width: 50px; height: 20px;}
tbody tr:last-of-type {border-bottom: 2px solid #009879;}
#popup { position: absolute; background-color: white; border: 1px solid #ccc; padding: 10px; z-index: 10; display: none; max-width: 400px; word-wrap: break-word;}
#popup .title {display:block; font-weight:bold; padding-bottom:10px}
#popup button { display:block; margin-top: 10px; }
</style></head><body><table><thead><tr><th style="width: 220px;">Color Code</th><th>Color</th></tr></thead><tbody>`;
colors.forEach(color => {
tableHTML += `<tr><td>${color}</td><td class="color-patch" data-color="${color}"><div style="width: 50px; height: 20px; background-color: ${color};"></div></td></tr>`;
});
tableHTML += '</tbody></table><div id="popup"></div></body></html>';
const newWindows = [];
function openColorTable(colors) {
const newWindow = window.open('', '_blank');
if (newWindow) {
newWindows.push(newWindow);
newWindow.document.write(tableHTML);
newWindow.document.close();
const table = newWindow.document.querySelector('table');
const popup = newWindow.document.getElementById('popup');
let isDragging = false;
let offsetX, offsetY;
popup.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - popup.offsetLeft;
offsetY = e.clientY - popup.offsetTop;
});
newWindow.document.addEventListener('mousemove', (e) => {
if (isDragging) {
popup.style.left = (e.clientX - offsetX) + 'px';
popup.style.top = (e.clientY - offsetY) + 'px';
}
});
newWindow.document.addEventListener('mouseup', () => {
isDragging = false;
});
newWindow.document.addEventListener('mouseleave', () => {
isDragging = false;
});
table.addEventListener('mouseover', (event) => {
if (event.target.classList.contains('color-patch')) {
const color = event.target.dataset.color;
const elementsWithColor = new Set(); // Use a Set to store unique elements
elements.forEach(el => {
const styles = window.getComputedStyle(el);
for (let i = 0; i < styles.length; i++) {
const property = styles[i];
if (property.includes('color') && styles.getPropertyValue(property) === color) {
elementsWithColor.add(getCssPath(el)); // Add to the Set (duplicates are ignored)
break;
}
}
});
// Convert the Set to an array and then join:
const uniqueElements = Array.from(elementsWithColor);
popup.innerHTML = `<div class="title">Elements using ${color}:</div>${uniqueElements.join('<br><br>')}<button onclick="this.parentNode.style.display='none'">Close</button>`;
const rect = event.target.getBoundingClientRect();
popup.style.left = (rect.right + 10) + 'px';
popup.style.top = rect.top + 'px';
popup.style.display = 'block';
function clickHandler(event) { // Define clickHandler here
popup.style.display = 'block';
event.target.removeEventListener('click', clickHandler); // Remove this specific handler
}
event.target.addEventListener('click', clickHandler);
}
});
} else {
alert('Please allow popups for this site to view the color table.');
}
}
openColorTable(colors);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment