Por que o HTML acha que "chucknorris" é uma cor?

7488

Como certas seqüências aleatórias produzem cores quando inseridas como cores de segundo plano em HTML? Por exemplo:

<body bgcolor="chucknorris"> test </body>

... produz um documento com um fundo vermelho em todos os navegadores e plataformas.

Curiosamente, enquanto chucknorri produz um fundo vermelho, chucknorrproduz um fundo amarelo.

O que está acontecendo aqui?

user456584
fonte
154
Como uma observação lateral: não use bgcolor. Use CSS background.
John Dvorak
47
Por que você deseja adicionar uma cor de plano de fundo chamada chucknorris? Qual era a cor esperada?
masterFly
106
@masterFly: Não sei por que meu comentário sob a resposta aceita foi excluído por ser "não construtivo", porque responde muito bem à sua pergunta: as pessoas experimentam essas coisas o tempo todo. Eu tinha apenas 10 anos quando descobri isso e tudo o que eu estava fazendo na época foi brincar e ver o que aconteceu. Você nem sempre precisa ter um motivo prático para fazer algo, especialmente algo tão frívolo como esse.
BoltClock
49
e o <body bgcolor="stevensegal">teste </body> é verde
Chris
4
@ BenDaggers Leia o histórico de revisões antes de fazer outra edição. A tag css é irrelevante e já foi removida duas vezes.
Lightness Races em órbita

Respostas:

6879

É uma ressaca dos dias do Netscape:

Os dígitos ausentes são tratados como 0 [...]. Um dígito incorreto é simplesmente interpretado como 0. Por exemplo, os valores # F0F0F0, F0F0F0, F0F0F, #FxFxFx e FxFxFx são iguais.

É da postagem do blog Um pouco sobre a análise de cores do Microsoft Internet Explorer, que o aborda com muitos detalhes, incluindo comprimentos variados de valores de cores, etc.

Se aplicarmos as regras à vez na postagem do blog, obteremos o seguinte:

  1. Substitua todos os caracteres hexadecimais não válidos pelos zeros

    chucknorris becomes c00c0000000
  2. Coloque o próximo número total de caracteres divisíveis por 3 (11 -> 12)

    c00c 0000 0000
  3. Divida em três grupos iguais, com cada componente representando o componente de cor correspondente de uma cor RGB:

    RGB (c00c, 0000, 0000)
  4. Truncar cada um dos argumentos da direita para baixo para dois caracteres

O que fornece o seguinte resultado:

RGB (c0, 00, 00) = #C00000 or RGB(192, 0, 0)

Aqui está um exemplo demonstrando o bgcoloratributo em ação, para produzir essa amostra de cores "incrível":

<table>
  <tr>
    <td bgcolor="chucknorris" cellpadding="8" width="100" align="center">chuck norris</td>
    <td bgcolor="mrt"         cellpadding="8" width="100" align="center" style="color:#ffffff">Mr T</td>
    <td bgcolor="ninjaturtle" cellpadding="8" width="100" align="center" style="color:#ffffff">ninjaturtle</td>
  </tr>
  <tr>
    <td bgcolor="sick"  cellpadding="8" width="100" align="center">sick</td>
    <td bgcolor="crap"  cellpadding="8" width="100" align="center">crap</td>
    <td bgcolor="grass" cellpadding="8" width="100" align="center">grass</td>
  </tr>
</table>

Isso também responde à outra parte da pergunta; por que bgcolor="chucknorr"produz uma cor amarela? Bem, se aplicarmos as regras, a string será:

c00c00000 => c00 c00 000 => c0 c0 00 [RGB(192, 192, 0)]

O que dá uma cor ouro amarelo claro. À medida que a string começa com 9 caracteres, mantemos o segundo C dessa vez; portanto, ele termina no valor final da cor.

Eu encontrei isso originalmente quando alguém apontou que você poderia fazer color="crap"e, bem, sai marrom.

traço
fonte
174
Note-se que, apesar do que aquele post diz, quando você começa a lidar com cordas 3 char-, você duplicar cada personagem, ao invés de prepending 0. isto é, 0F6torna-se #00FF66, não #000F06.
Aaron Dufour
634
@usr:;) HTML é construído em torno de entrada malformado intencionalmente ignorando
Lily Ballard
59
Você também pode usar minha string aleatória no conversor de cores css para obter a cor de uma string específica. É baseado nas 5 etapas para calcular a cor da sequência de Jeremy Goodell .
TimPietrusky
15
Uma oportunidade oculta para semântica? Você pode fazer algumas páginas de erro com isso: <body bgcolor=error><h1 style=text-align:center>Error: Not Found<h1></span>Você pode adicionar uma div com outro fundo ou algo parecido, para que não seja tão esteticamente chocante.
Theraot
32
@Theraot também bgcolor="success"é um verde agradável. Curiosamente, é possível substituir essas cores usando seletores de atributo / valor CSS (por exemplo, td[bgcolor="chucknorris"] {...}).
Daiscog 01/03
970

Lamento discordar, mas de acordo com as regras para analisar um valor de cor herdado postado por @Yuhong Bao , chucknorrisNÃO equivale a #CC0000, mas sim #C00000, a um tom de vermelho muito semelhante, mas um pouco diferente. Usei o complemento Firefox ColorZilla para verificar isso.

As regras declaram:

  • torne a string um comprimento múltiplo de 3 adicionando 0s: chucknorris0
  • separe a cadeia em três cadeias de comprimento igual: chuc knor ris0
  • truncar cada sequência para 2 caracteres: ch kn ri
  • mantenha os valores hexadecimais e adicione 0 quando necessário: C0 00 00

Consegui usar essas regras para interpretar corretamente as seguintes seqüências de caracteres:

  • LuckyCharms
  • Luck
  • LuckBeALady
  • LuckBeALadyTonight
  • GangnamStyle

ATUALIZAÇÃO: Os respondentes originais que disseram que a cor era #CC0000editaram suas respostas para incluir a correção.

Jeremy Goodell
fonte
86
Eu descobri, eu tinha interpretado mal algumas das instruções de análise: "adamlevine" = "ada00e000e" = "ada00e000e00" = "ada0 0e00 0e00" = "ad 0e 0e" - Perfeito !!
21412 Jeremy Goodell
17
Caso você esteja interessado, publiquei o algoritmo de 5 etapas como uma atualização em uma pergunta semelhante que publiquei hoje: stackoverflow.com/questions/12939234/…
Jeremy Goodell
18
A @TimPietrusky criou esta incrível ferramenta de demonstração para nomes de cores aleatórios. Basta ir aqui: randomstringtocsscolor.com e clicar na caixa e digite "chucknorris".
Jeremy Goodell
4
adamlevinefunciona de acordo com jsfiddle.net/LdyZ8/2959, mas as letras são bloqueadas nas ada00e000equais é preenchida, ada00e000e00mas depois reduzida ao valor típico de seis dígitos HEX [ad]a0[0e]00[0e]00, tornando ad0e0e que aparece no jsfiddle acima.
Martin Martin
4
Seria melhor se essa resposta contivesse apenas o estado atual - o histórico dessa resposta e de outras respostas pertence aos resumos e / ou comentários de edição.
Peter Mortensen
397

A maioria dos navegadores simplesmente ignora qualquer valor não hexadecimal na seqüência de cores, substituindo dígitos não hexadecimais por zeros.

ChuCknorristraduz para c00c0000000. Neste ponto, o navegador irá dividir a string em três partes iguais, indicando Vermelho , Verde e Azul valores: c00c 0000 0000. Bits extras em cada seção serão ignorados, o que faz com que o resultado final #c00000seja de uma cor avermelhada.

Observe que isso não se aplica à análise de cores CSS, que segue o padrão CSS.

<p><font color='chucknorris'>Redish</font></p>
<p><font color='#c00000'>Same as above</font></p>
<p><span style="color: chucknorris">Black</span></p>

Mike Christensen
fonte
7
Embora eu ainda esteja curioso para saber por que o OP disse "em CSS" e não "em HTML" - Talvez eles estejam usando um navegador super antigo ou apenas estejam enganados?
Mike Christensen
7
Portanto, é mais provável que ele use o bgcoloratributo obsoleto .
animuson
12
Caracteres inválidos não são ignorados, eles são tratados como 0.
tratar os seus mods bem
5
(Embora essa resposta esteja inoperante) sugestão: use a cor de fundo para demonstrar as cores. Cor do texto é sobre uma área tão pequena relativa é difícil ver as diferenças ou semelhanças
Zoe
304

O navegador está tentando converter chucknorrisem código de cor hexadecimal, porque não é um valor válido.

  1. Em chucknorris, tudo, exceto cnão é um valor hexadecimal válido.
  2. Por isso, é convertido para c00c00000000.
  3. Que se torna # c00000 , um tom de vermelho.

Esse parece ser um problema principalmente no Internet Explorer e Opera (12), pois o Chrome (31) e o Firefox (26) simplesmente ignoram isso.

PS Os números entre parênteses são as versões do navegador em que testei.

.

Em uma nota mais clara

Chuck Norris não está de acordo com os padrões da web. Os padrões da Web estão em conformidade com ele. # BADA55

aWebDeveloper
fonte
297

O motivo é que o navegador não consegue entendê- lo e tenta traduzi-lo de alguma forma para o que ele pode entender e, neste caso, em um valor hexadecimal! ...

chucknorriscomeça com o cqual é reconhecido caractere em hexadecimal, também está convertendo todos os caracteres não reconhecidos em 0!

Assim, chucknorrisno formato hexadecimal torna-se:, c00c00000000todos os outros caracteres se tornam 0e cpermanecem onde estão ...

Agora eles são divididos por 3 para RGB(vermelho, verde, azul) ... R: c00c, G: 0000, B:0000...

Mas sabemos que o hexadecimal válido para RGB é de apenas 2 caracteres, significa R: c0, G: 00, B:00

Portanto, o resultado real é:

bgcolor="#c00000";

Também adicionei as etapas na imagem como uma referência rápida para você:

Por que o HTML acha que "chucknorris" é uma cor?

Alireza
fonte
23
Esta é uma explicação tão fofa: D: D: D
Dominik Bucher
2
Explicação tão sábia, muito simples e direta que eu já experimentei
Saurin Vala
1
resposta muito criativa :)
ahmednawazbutt
222

A especificação HTML do WHATWG possui o algoritmo exato para analisar um valor de cor herdado: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value

O código que o Netscape Classic usado para analisar seqüências de cores é de código aberto: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155

Por exemplo, observe que cada caractere é analisado como um dígito hexadecimal e, em seguida, é deslocado para um número inteiro de 32 bits sem verificar o estouro . Apenas oito dígitos hexadecimais cabem em um número inteiro de 32 bits, e é por isso que apenas os últimos 8 caracteres são considerados. Depois de analisar os dígitos hexadecimais em números inteiros de 32 bits, eles são truncados em números inteiros de 8 bits, dividindo-os por 16 até que se encaixem em 8 bits, e é por isso que os zeros à esquerda são ignorados.

Atualização: esse código não corresponde exatamente ao definido na especificação, mas a única diferença é que existem algumas linhas de código. Eu acho que foram essas linhas que foram adicionadas (no Netscape 4):

if (bytes_per_val > 4)
{
      bytes_per_val = 4;
}
Yuhong Bao
fonte
Obrigado, você me mostrou onde está o antigo código fonte do Netscape ... por que é tão difícil de encontrar?
kb1000 18/03
202

Responda:

  • O navegador tentará converter chucknorris em um valor hexadecimal.
  • Como cé o único caractere hexadecimal válido em chucknorris , o valor se transforma em: c00c00000000( 0 para todos os valores inválidos ).
  • O navegador, em seguida, divide o resultado em 3 groupds: Red = c00c, Green = 0000, Blue = 0000.
  • Como os valores hexadecimais válidos para planos de fundo html contêm apenas 2 dígitos para cada tipo de cor ( r , g , b ), os últimos 2 dígitos são truncados em cada grupo, deixando um valor rgb com c00000uma cor de tom avermelhado.
Webeng
fonte
22

chucknorris começa com c , e o navegador lê em um valor hexadecimal.

Porque A, B, C, D, E e F são caracteres em hexadecimal .

O navegador é convertido chucknorrisem um valor hexadecimal,C00C00000000 ,.

Em seguida, o C00C00000000valor hexadecimal é convertido para o formato RGB (dividido por 3):

C00C00000000 => R:C00C, G:0000, B:0000

O navegador precisa de apenas dois dígitos para indicar a cor:

R:C00C, G:0000, B:0000=> R:C0, G:00, B:00=>C00000

Por fim, mostre bgcolor = C00000no navegador da web.

Aqui está um exemplo de demonstração:

<table>
  <tr>
    <td bgcolor="chucknorris" cellpadding="10" width="150" align="center">chucknorris</td>
    <td bgcolor="c00c00000000" cellpadding="10" width="150" align="center">c00c00000000</td>
    <td bgcolor="c00000" cellpadding="10" width="150" align="center">c00000</td>
  </tr>
</table>

sameera lakshitha
fonte
15

As regras para analisar cores em atributos herdados envolvem etapas adicionais além das mencionadas nas respostas existentes. O componente truncado para a parte de 2 dígitos é descrito como:

  1. Descartar todos os personagens, exceto os últimos 8
  2. Descarte os zeros à esquerda um por um , desde que todos os componentes tenham um zero à esquerda
  3. Descartar todos os personagens, exceto os 2 primeiros

Alguns exemplos:

oooFoooFoooF
000F 000F 000F                <- replace, pad and chunk
0F 0F 0F                      <- leading zeros truncated
0F 0F 0F                      <- truncated to 2 characters from right

oooFooFFoFFF
000F 00FF 0FFF                <- replace, pad and chunk
00F 0FF FFF                   <- leading zeros truncated
00 0F FF                      <- truncated to 2 characters from right

ABCooooooABCooooooABCoooooo
ABC000000 ABC000000 ABC000000 <- replace, pad and chunk
BC000000 BC000000 BC000000    <- truncated to 8 characters from left
BC BC BC                      <- truncated to 2 characters from right

AoCooooooAoCooooooAoCoooooo
A0C000000 A0C000000 A0C000000 <- replace, pad and chunk
0C000000 0C000000 0C000000    <- truncated to 8 characters from left
C000000 C000000 C000000       <- leading zeros truncated
C0 C0 C0                      <- truncated to 2 characters from right

Abaixo está uma implementação parcial do algoritmo. Ele não trata de erros ou casos em que o usuário insere uma cor válida.

Salman A
fonte