Como obter o valor da cor hexadecimal em vez do valor RGB?


171

O uso do jQuery a seguir obterá o valor RGB da cor de fundo de um elemento:

$('#selector').css('backgroundColor');

Existe uma maneira de obter o valor hexadecimal em vez do RGB?


2
Sobre um tópico relacionado, existem mais maneiras (e sem dúvida melhores) de converter cores hexadecimais e RGB: stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb Essa roda foi reinventada várias vezes para construir um trem rodoviário. Eu esperava que uma das bibliotecas JS populares, mais simples que menos, tivesse uma função de utilitário.
— Michael Scheper

Lembre-se de que alguns navegadores retornam rgba (#, #, #, #), como rgba (0,0,0,0), que é transparente, não preto. O quarto valor é a opacidade, com 1,0 sendo 100% colorido e 0,5 sendo 50%.
— Twelve24

Respostas:


141
var hexDigits = new Array
        ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"); 

//Function to convert rgb color to hex format
function rgb2hex(rgb) {
 rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
 return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

function hex(x) {
  return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
 }

( Fonte )


7
+1, você pode usar Number.toString (16) - pelo menos para cada dígito hexadecimal (ou bloco com 0 se for menor de 16 anos)
— orip

19
-1. Conforme mencionado pelo orip, você pode usar toString (16). Votado por outras ineficiências. Se você declarar hexDigits em todas as chamadas de função, faça-o pelo menos no corpo da função do rgb2hex (não no corpo do hex), para que a matriz não seja redefinida 3 vezes por 1 chamada para rgb2hex. Aprenda também a usar 'var', para não poluir o escopo global.
— Matt

3
Esse método não parece muito tolerante em diferenciar espaço em branco ou capitalização. jsfiddle.net/Xotic750/pSQ7d
— Xotic750

1
Se você realmente quer ser pedante, pode tornar o regex mais permissivo: rgb.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i)No entanto, o regex fornecido foi projetado para lidar com o formato fornecido por um navegador ao usar o jQuery, e isso não tem as consistências de espaço em branco ou captilização diferentes você está falando sobre. Você também pode usar o mesmo regex e apenas remover todos os espaços em branco e converter em minúsculas antes de fazer a correspondência em rgb. PS Seu exemplo do violino: 'rgb (10, 128,)' Eu não acho que isso seja razoável para testar
— fichário

e para mim o retorno de jquery css background-colors vem em formato com rgba, portanto isso não funciona.
— Miguel

159

Aqui está a solução mais limpa que escrevi com base na sugestão do @Matt:

function rgb2hex(rgb) {
    rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    function hex(x) {
        return ("0" + parseInt(x).toString(16)).slice(-2);
    }
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

Alguns navegadores já retornam cores como hexadecimais (no Internet Explorer 8 e abaixo). Se você precisar lidar com esses casos, basta anexar uma condição dentro da função, como o @gfrobenius sugeriu:

function rgb2hex(rgb) {
    if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb;

    rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    function hex(x) {
        return ("0" + parseInt(x).toString(16)).slice(-2);
    }
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

Se você estiver usando o jQuery e quiser uma abordagem mais completa, poderá usar os CSS Hooks disponíveis desde o jQuery 1.4.3, como mostrei ao responder a esta pergunta: Posso forçar o retorno do jQuery.css ("backgroundColor") no formato hexadecimal?


2
Sugiro a todos: dê uma olhada na minha resposta aqui para ver uma versão aprimorada usando os ganchos CSS do jQuery .
— precisa saber é o seguinte

1
@Ghigo, desculpe, mas você está errado. IE8 já retorna como cores hexadecimal quando chegar o estilo atual, desta forma: document.getElementById("your_id").currentStyle["backgroundColor"]. A função rgb2hex()não é necessária. Aqui está o plugin jQuery usando CSS Ganchos que eu sugeri acima, que já faz todas as validações para recuperar as cores em diferentes navegadores: stackoverflow.com/questions/6177454/...
— Erick Petrucelli

2
@Ghigo, acho que você entendeu errado: você NÃO DEVE usar essa função se estiver em um navegador que retorne em HEX. Esta função converte RGB em HEX e apenas isso. Não use quando não estiver em RGB. O fato de você precisar de uma solução mais completa (que detecta se o valor já é RGB, como feito por @ Jim-F) não altera o fato de que essa solução oferece exatamente o que foi solicitado pelo OP. Seu voto negativo não faz sentido, desculpe.
— Erick Petrucelli 27/03

4
Sinto muito, mas não concordo. Uma função entre navegadores é sempre melhor do que aquela que precisa de execução com base na detecção do navegador. Op pediu para converter $('#selector').css('backgroundColor')para hex, não um valor rgb para hex. E no IE8, $('#selector').css('backgroundColor')já é hexadecimal, por isso deve ser tratado. É isso aí. Não fique com raiva de mim :)
— Ghigo

1
Faça isso pessoal, um liner simples que eu adicionei à rgb2hex()função, obrigado @ErickPetru! Eu tenho que codificar de volta para o IE7, acredite ou não. Com IE7 e 8 .css('backgroundColor')nativos obj.style.backgroundColor, retornará hexadecimal, não RGB, então adicionei isso como a primeira linha norgb2hex() função na resposta fornecida, para que funcione todo o caminho de volta ao IE7: /* IE7&8 will return hex, so no need to run this function if it is already hex. */ if (/^#[0-9A-F]{6}$/i.test(rgb)) return rgb.substring(1, 7); //I'm doing a subtring here because I do not want the leading # symbolEspero que ajude.
— Gfrobenius #

61

A maioria dos navegadores parece retornar o valor RGB ao usar:

$('#selector').css('backgroundColor');

Somente o IE (apenas 6 testados até o momento) retorna o valor Hex.

Para evitar mensagens de erro no IE, você pode agrupar a função em uma instrução if:

function rgb2hex(rgb) {
     if (  rgb.search("rgb") == -1 ) {
          return rgb;
     } else {
          rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
          function hex(x) {
               return ("0" + parseInt(x).toString(16)).slice(-2);
          }
          return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); 
     }
}

1
Este funciona melhor que a maioria dos outros, já que Jim leva em conta o rgba, que é o que o Safari (pelo menos no Mac OS X) usa. Obrigado Jim!
— Pascal Lindelauf 6/06/11

1
Ótima solução. Observe que a função retorna letras minúsculas, ou seja, # ff5544 e não # FF5544.
— Peter Peter

Esse regex também suporta canais aplha na solução acima rgb = rgb.match (/ ^ rgba? ((\ D +), \ s * (\ d +), \ s * (\ d +) (?:, \ S * (0 \. \ D +))?) $ /);
— Henning Winter

trabalho como um encanto
— ucMedia

22

Atualizado @ErickPetru para compatibilidade com rgba:

function rgb2hex(rgb) {
    rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
    function hex(x) {
        return ("0" + parseInt(x).toString(16)).slice(-2);
    }
    return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}

Atualizei o regex para corresponder ao valor alfa, se definido, mas não para usá-lo.


Apenas para completar: estou trabalhando em algo que será exportado para o PowerPoint (não pergunte ...) e ele aceita um quarto byte na cadeia hexadecimal do canal alfa, para que você possa usá-lo assim: return hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]) /* Add the alpha channel if it exists */ + (rgb[5] !== undefined ? hex(Math.round(rgb[5] * 255)) : ''); Também estou removendo o #símbolo para torná-lo independente do uso final (pode-se obter a saída e anexá-la 0xpor exemplo, ou deixá-la sem prefixo). Espero que ajude alguém!
— Óscar Gómez Alcañiz

10

Aqui está um liner do ES6 que não usa jQuery:

var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => parseInt(color).toString(16)).join('');

1
Obrigado, isso me ajudou a incorporá-lo em uma página do Wordpress que retira as barras invertidas do regex nas respostas anteriores.
— Jason

5

Aqui está uma versão que também verifica a transparência. Eu precisava disso, pois meu objetivo era inserir o resultado em um atributo de estilo, onde a versão transparente de uma cor hexadecimal é na verdade a palavra "transparente".

function rgb2hex(rgb) {
     if (  rgb.search("rgb") == -1 ) {
          return rgb;
     }
     else if ( rgb == 'rgba(0, 0, 0, 0)' ) {
         return 'transparent';
     }
     else {
          rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
          function hex(x) {
               return ("0" + parseInt(x).toString(16)).slice(-2);
          }
          return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); 
     }
}

4

Função que retorna a cor de fundo de um elemento em hexadecimal.

function getBgColorHex(elem){
    var color = elem.css('background-color')
    var hex;
    if(color.indexOf('#')>-1){
        //for IE
        hex = color;
    } else {
        var rgb = color.match(/\d+/g);
        hex = '#'+ ('0' + parseInt(rgb[0], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2);
    }
    return hex;
}

exemplo de uso:

$('#div1').click(function(){
   alert(getBgColorHex($(this));
}

jsfiddle


4

Mesma resposta como resposta de Jim F, mas sintaxe ES6 , portanto, menos instruções:

const rgb2hex = (rgb) => {
  if (rgb.search("rgb") === -1) return rgb;
  rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
  const hex = (x) => ("0" + parseInt(x).toString(16)).slice(-2);
  return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
};

3

classe de cores retirada do seletor de cores de inicialização

// Color object
var Color = function(val) {
    this.value = {
        h: 1,
        s: 1,
        b: 1,
        a: 1
    };
    this.setColor(val);
};

Color.prototype = {
    constructor: Color,

    //parse a string to HSB
    setColor: function(val){
        val = val.toLowerCase();
        var that = this;
        $.each( CPGlobal.stringParsers, function( i, parser ) {
            var match = parser.re.exec( val ),
            values = match && parser.parse( match ),
            space = parser.space||'rgba';
            if ( values ) {
                if (space === 'hsla') {
                    that.value = CPGlobal.RGBtoHSB.apply(null, CPGlobal.HSLtoRGB.apply(null, values));
                } else {
                    that.value = CPGlobal.RGBtoHSB.apply(null, values);
                }
                return false;
            }
        });
    },

    setHue: function(h) {
        this.value.h = 1- h;
    },

    setSaturation: function(s) {
        this.value.s = s;
    },

    setLightness: function(b) {
        this.value.b = 1- b;
    },

    setAlpha: function(a) {
        this.value.a = parseInt((1 - a)*100, 10)/100;
    },

    // HSBtoRGB from RaphaelJS
    // https://github.com/DmitryBaranovskiy/raphael/
    toRGB: function(h, s, b, a) {
        if (!h) {
            h = this.value.h;
            s = this.value.s;
            b = this.value.b;
        }
        h *= 360;
        var R, G, B, X, C;
        h = (h % 360) / 60;
        C = b * s;
        X = C * (1 - Math.abs(h % 2 - 1));
        R = G = B = b - C;

        h = ~~h;
        R += [C, X, 0, 0, X, C][h];
        G += [X, C, C, X, 0, 0][h];
        B += [0, 0, X, C, C, X][h];
        return {
            r: Math.round(R*255),
            g: Math.round(G*255),
            b: Math.round(B*255),
            a: a||this.value.a
        };
    },

    toHex: function(h, s, b, a){
        var rgb = this.toRGB(h, s, b, a);
        return '#'+((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
    },

    toHSL: function(h, s, b, a){
        if (!h) {
            h = this.value.h;
            s = this.value.s;
            b = this.value.b;
        }
        var H = h,
        L = (2 - s) * b,
        S = s * b;
        if (L > 0 && L <= 1) {
            S /= L;
        } else {
            S /= 2 - L;
        }
        L /= 2;
        if (S > 1) {
            S = 1;
        }
        return {
            h: H,
            s: S,
            l: L,
            a: a||this.value.a
        };
    }
};

Como usar

var color = new Color("RGB(0,5,5)");
color.toHex()

3

Legível e& Reg-exp grátis (sem Reg-exp)

Eu criei uma função que usa funções básicas legíveis e sem reg-exps.
A função aceita cores nos formatos hex, rgb ou rgba CSS e retorna a representação hexadecimal.
EDIT: houve um erro ao analisar o formato rgba (), corrigido ...

function getHexColor( color ){
    //if color is already in hex, just return it...
    if( color.indexOf('#') != -1 ) return color;
    
    //leave only "R,G,B" :
    color = color
                .replace("rgba", "") //must go BEFORE rgb replace
                .replace("rgb", "")
                .replace("(", "")
                .replace(")", "");
    color = color.split(","); // get Array["R","G","B"]
    
    // 0) add leading #
    // 1) add leading zero, so we get 0XY or 0X
    // 2) append leading zero with parsed out int value of R/G/B
    //    converted to HEX string representation
    // 3) slice out 2 last chars (get last 2 chars) => 
    //    => we get XY from 0XY and 0X stays the same
    return  "#"
            + ( '0' + parseInt(color[0], 10).toString(16) ).slice(-2)
            + ( '0' + parseInt(color[1], 10).toString(16) ).slice(-2)
            + ( '0' + parseInt(color[2], 10).toString(16) ).slice(-2);
}

1
Não funciona com rgba (0,0,0,0). Primeiro: a ordem precisa mudar. .replace("rgba", "") .replace("rgb", "") .replace("(", "") .replace(")", "");Caso contrário, você fica com a0,0,0,0. E retorna # 000000, que é preto, em vez de transparente.
— Twelve24

Se o quarto valor em um rgba for 0 (zero), então, para css, esse 'elemento' seria: elemento {color: # 000000, opacidade: 0,0;} que é transparente ou apenas retorna condicionalmente o 'rgba (0,0 , 0,0) 'volta para o chamador.
— Twelve24

@ Twelve24 Análise corrigida - Na verdade, notei que antes de ler seu comentário, mas definitivamente obrigado por isso :), Quanto à transparência - a função deve retornar a cor HEXA, ou a "cor base" - para que uma seja de propósito :)
— jave.web 18/06/2015

3

Experimentar

// c - color str e.g."rgb(12,233,43)", result color hex e.g. "#0ce92b"
let rgb2hex= c=> '#'+c.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``


2

Este parece um pouco melhor:

var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var r   = parseInt(rgb[0], 10);
var g   = parseInt(rgb[1], 10);
var b   = parseInt(rgb[2], 10);
var hex = '#'+ r.toString(16) + g.toString(16) + b.toString(16);

uma linha mais sucinta:

var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var hex = '#'+ Number(rgb[0]).toString(16) + Number(rgb[1]).toString(16) + Number(rgb[2]).toString(16);

forçando o jQuery a sempre retornar hex:

$.cssHooks.backgroundColor = {
    get: function(elem) {
        if (elem.currentStyle)
            var bg = elem.currentStyle["backgroundColor"];
        else if (window.getComputedStyle) {
            var bg = document.defaultView.getComputedStyle(elem,
                null).getPropertyValue("background-color");
        }
        if (bg.search("rgb") == -1) {
            return bg;
        } else {
            bg = bg.match(/\d+/g);
            function hex(x) {
                return ("0" + parseInt(x).toString(16)).slice(-2);
            }
            return "#" + hex(bg[0]) + hex(bg[1]) + hex(bg[2]);
        }
    }
}

2

Só para adicionar à resposta de @ Justin acima ..

deveria ser

var rgb = document.querySelector('#selector').style['background-color'];
return '#' + rgb.substr(4, rgb.indexOf(')') - 4).split(',').map((color) => String("0" + parseInt(color).toString(16)).slice(-2)).join('');

Como as funções parse int acima truncam os zeros à esquerda, produz códigos de cores incorretos de 5 ou 4 letras, podendo ser ... ou seja, para rgb (216, 160, 10), produz # d8a0a enquanto # d8a00a.

obrigado


1

Aqui está uma solução que descobri que não gera erros de script no IE: http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx


Nas versões mais antigas do IE, buscar um valor de cor de um objeto usando jquery às vezes pode retornar hex em vez de rgb, enquanto a maioria dos navegadores modernos retornam RGB. A função vinculada à lida com os dois casos de uso
— Paul T

1

A resposta de Steven Pribilinskiy diminui os zeros à esquerda, por exemplo # ff0000 se torna # ff00.

Uma solução é anexar um 0 inicial e uma subcadeia dos 2 últimos dígitos.

var rgb = $('#selector').css('backgroundColor').match(/\d+/g);
var hex = '#'+ String('0' + Number(rgb[0]).toString(16)).slice(-2) + String('0' + Number(rgb[1]).toString(16)).slice(-2) + String('0' + Number(rgb[2]).toString(16)).slice(-2);

1

Como a pergunta estava usando JQuery, aqui está um plugin JQuery baseado no código de Daniel Elliott:

$.fn.cssAsHex = function(colorProp) {

    var hexDigits = '0123456789abcdef';

    function hex(x) {
        return isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
    };

    // Convert RGB color to Hex format
    function rgb2hex(rgb) {
        var rgbRegex = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
        return '#' + hex(rgbRegex[1]) + hex(rgbRegex[2]) + hex(rgbRegex[3]);
    };

    return rgb2hex(this.css(colorProp));
};

Use-o como:

var hexBackgroundColor = $('#myElement').cssAsHex('background-color');

0

Aqui está a minha solução, também faz caso do uso de um argumento e verifica outros possíveis espaços em branco e letras maiúsculas na string fornecida.

var a = "rgb(10, 128, 255)";
var b = "rgb( 10, 128, 255)";
var c = "rgb(10, 128, 255 )";
var d = "rgb ( 10, 128, 255 )";
var e = "RGB ( 10, 128, 255 )";
var f = "rgb(10,128,255)";
var g = "rgb(10, 128,)";

var rgbToHex = (function () {
    var rx = /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;

    function pad(num) {
        if (num.length === 1) {
            num = "0" + num;
        }

        return num;
    }

    return function (rgb, uppercase) {
        var rxArray = rgb.match(rx),
            hex;

        if (rxArray !== null) {
            hex = pad(parseInt(rxArray[1], 10).toString(16)) + pad(parseInt(rxArray[2], 10).toString(16)) + pad(parseInt(rxArray[3], 10).toString(16));

            if (uppercase === true) {
                hex = hex.toUpperCase();
            }

            return hex;
        }

        return;
    };
}());

console.log(rgbToHex(a));
console.log(rgbToHex(b, true));
console.log(rgbToHex(c));
console.log(rgbToHex(d));
console.log(rgbToHex(e));
console.log(rgbToHex(f));
console.log(rgbToHex(g));

Em jsfiddle

Comparação de velocidade em jsperf

Uma melhoria adicional poderia ser trim()a rgbstring

var rxArray = rgb.trim().match(rx),

0

Minha bela solução não-padrão

HTML

<div id="selector" style="background-color:#f5b405"></div>

jQuery

$("#selector").attr("style").replace("background-color:", "");

Resultado

#f5b405

1
Retorna tudo no estilo. : c
— Eddie
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.